Resources

Code examples

The whole integration is two server-side requests and a redirect. The samples on the right run the full flow in PHP (Guzzle), cURL and Node.js — pick one and swap in your own values.

  1. Get an access token. POST /authentication/token with your client_id and secret_id. The token expires after 600 seconds, so request one per checkout session.
  2. Create the payment. POST /payment/create with the Bearer token. amount is a string with 2 decimal places; currency is an upper-case alpha-3 code enabled on your account.
  3. Redirect the customer. Store data.token against your order, then send the customer to data.payment_url.
  4. Verify on return. QRPay redirects the customer to your return_url with the payment result — match the token to your stored order and keep trx_id as QRPay’s transaction reference. See Verify payment.

Placeholders

{{base_url}}https://{your-qrpay-domain}/pay/api/v1 — the demo server is https://qrpaypro.appdevs.net/pay/api/v1. Same base URL for sandbox and production; the key’s mode decides the environment.
{{client_id}} / {{secret_id}}Your Client/Primary key and Secret key from the merchant panel. Keep them server-side only.

A complete working integration is on GitHub: QRPay-Gateway-Example.

Test safely
  • New keys start in SANDBOX mode — no real money moves until you switch the key to PRODUCTION in the merchant panel.
  • Treat a payment as paid only when the return-URL token matches an order you created — never from client-side state.
Full flow PHP · Guzzle
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

// 1. Get an access token (expires in 600s)
$response = $client->request('POST',
  '{{base_url}}/authentication/token', [
  'json' => [
    'client_id' => '{{client_id}}',
    'secret_id' => '{{secret_id}}',
  ],
  'headers' => [
    'accept'       => 'application/json',
    'content-type' => 'application/json',
  ],
]);

$accessToken = json_decode(
  $response->getBody(), true
)['data']['access_token'];

// 2. Create the payment — amount is a string
$response = $client->request('POST',
  '{{base_url}}/payment/create', [
  'json' => [
    'amount'     => '100.00',
    'currency'   => 'USD',
    'return_url' => 'https://example.com/order/done',
    'cancel_url' => 'https://example.com/order/cancel',
  ],
  'headers' => [
    'Authorization' => 'Bearer ' . $accessToken,
    'accept'        => 'application/json',
    'content-type'  => 'application/json',
  ],
]);

$data = json_decode($response->getBody(), true)['data'];

// 3. Store $data['token'] against your order,
//    then redirect to the hosted checkout
header('Location: ' . $data['payment_url']);
exit;
Full flow cURL
# 1. Get an access token (expires in 600s)
curl -X POST '{{base_url}}/authentication/token' \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -d '{
    "client_id": "{{client_id}}",
    "secret_id": "{{secret_id}}"
  }'

# 2. Create the payment — amount is a string
curl -X POST '{{base_url}}/payment/create' \
  -H 'Authorization: Bearer {{access_token}}' \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -d '{
    "amount": "100.00",
    "currency": "USD",
    "return_url": "https://example.com/order/done",
    "cancel_url": "https://example.com/order/cancel"
  }'

# 3. Open data.payment_url in the browser
Full flow Node.js · fetch
const BASE_URL = '{{base_url}}';

// 1. Get an access token (expires in 600s)
const tokenRes = await fetch(
  `${BASE_URL}/authentication/token`, {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    client_id: '{{client_id}}',
    secret_id: '{{secret_id}}',
  }),
});
const { data: { access_token } } = await tokenRes.json();

// 2. Create the payment — amount is a string
const payRes = await fetch(`${BASE_URL}/payment/create`, {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${access_token}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    amount: '100.00',
    currency: 'USD',
    return_url: 'https://example.com/order/done',
    cancel_url: 'https://example.com/order/cancel',
  }),
});
const { data } = await payRes.json();

// 3. Store data.token against your order,
//    then redirect the customer
// res.redirect(data.payment_url);
On your return_url verified result
{
  "token": "2zMRmT3KeYT2BWMAyGhqEfuw4tOYOfGX...",
  "trx_id": "BP2c7sAvw75MTlrP",
  "payer": {
    "username": "testuser",
    "email": "user@appdevs.net"
  }
}