---
name: cas-qr-pay
description: "Integrate Cas QR Pay (scopes: qrpay): integration steps, the APIs to call and the pre-production checklist."
---

# Cas — QR Pay

> Source: https://cas.so/en/product/qr-pay · Markdown: https://cas.so/en/product/qr-pay.md

_This skill is generated from the Cas documentation. When you need details (schemas, error codes, examples), fetch the latest Markdown from the links below instead of guessing._

## When to use this skill

When integrating, extending or debugging Cas **QR Pay** in your system.

## Product summary

Create QR payment

QR PAY is a dynamic QR code generated per order with a built-in payment confirmation.

For each generated payment QR code, a **virtual account number** is also created and **linked to a corresponding order**.  
When the customer makes a payment to this virtual account, the associated order is automatically marked as successfully paid.

## Scopes

`qrpay`

## Integration flow

Below are the steps to integrate QR Pay into your product.

1. Create a grant [`/grant/token`](https://cas.so/en/general/api/grant/create.md) with `scopes` set to `qrpay`.
   - **user** (optional): the customer information already stored in your system, used to prefill the linking form
     on Cas Link and to validate it against the bank account information. [See details](#user-info)

2. Open the Cas Link interface using the `grantToken` returned in the previous step. [`See details`](https://cas.so/en/general/link.md)

3. After the user completes the authentication, your frontend will receive a `publicToken`, which you can use to obtain an `accessToken` for the grant.

4. Once you have the `accessToken`, call the [`Get QR Pay Account Identity API`](https://cas.so/en/general/api/get-qr-pay-identity.md) to verify if the account is valid.  
   If the account is invalid, you should call the [`/grant/remove API`](https://cas.so/en/general/api/grant/remove.md) to revoke the grant.

5. You can now call the [`Create QR Pay API`](https://cas.so/en/general/api/create-qr-pay.md).

6. Generate the QR code from the `qrCode` field in the response and display it in your interface.  
   To simplify generating VietQR codes, you can use the [`Quicklink from vietqr.io`](https://vietqr.io/danh-sach-api/link-tao-ma-nhanh/) to generate the QR code and embed the link into your system.

7. Handle the order status in your system when receiving a transaction [`webhook`](https://cas.so/en/general/api/webhook.md),  
   and the `referenceNumber` in the `paymentMeta` from the webhook corresponds to your internal order ID.

#### Customer information (`user`) {#user-info}

`user` is an **optional** field when creating a grant. If your system already stores the customer's information, send it so that Cas Link can:

- **Validate the bank account**: Cas Link compares the information you send with the account information returned by the bank.
If the account holder name or the identification number does not match, the linking flow is stopped and an error is shown to the user.
- **Prefill the linking form**: Cas Link fills in the account holder name, identification number, phone number and email,
so the user does not have to re-enter what you already have.

| Field | Type | Description |
| --- | --- | --- |
| `legalName` | string | Account holder name (individual) |
| `idNumber` | string | Personal identification number (ID card) of the account holder |
| `companyName` | string | Company name |
| `companyLegalId` | string | Tax code / business registration number |
| `mobileNumber` | string | Phone number registered with the bank |
| `email` | string | Customer email |

:::note
Depending on whether the financial service is of type **personal** or **enterprise**, Cas Link compares either
`legalName`/`idNumber` or `companyName`/`companyLegalId`. Any field you omit is skipped during the comparison.
:::

## APIs used in this flow

- [Webhook](https://cas.so/en/general/api/webhook.md)
- [Create grant token](https://cas.so/en/general/api/grant/create.md)
- [QR Pay Identity (Beta)](https://cas.so/en/general/api/get-qr-pay-identity.md)
- [Remove Grant](https://cas.so/en/general/api/grant/remove.md)
- [QR Pay](https://cas.so/en/general/api/create-qr-pay.md)
- [Exchange public token for an access token](https://cas.so/en/general/api/grant/exchange.md)

## Read before writing code

- [Cas core](https://cas.so/en/skills/cas-core/SKILL.md)
- [Cas Link](https://cas.so/en/general/link.md)
- [Webhook](https://cas.so/en/general/api/webhook.md)
- [Errors](https://cas.so/en/errors.md)

## Rules you must follow when writing code

- `clientId` / `secretKey` live on the server in environment variables only — never ship them to a client, never commit them.
- Request only the `scopes` the product needs; extra scopes mean extra cost and risk.
- Avoid duplicate grants: check your database for a live grant before opening Cas Link again.
- Store `accessToken` and `grantId` encrypted and linked to your user; one user may hold several grants. Never surface these values in the UI.
- Log `requestId` (on every response) and `grantId` (on grant-related responses) for every call — this is what Cas support needs to trace an issue.
- Every API call needs a timeout and backoff retry for transient failures; never blindly retry money-moving calls (use your own idempotency key).
- Webhooks: accept them only from Cas IPs, return 2xx fast and process asynchronously, and make handling idempotent — deliveries can repeat or arrive out of order.
- Handle `GRANT_LOGIN_REQUIRED` by reopening Cas Link in Update mode instead of making the user relink from scratch.
- Handle `GRANT` webhooks: `USER_PERMISSION_REVOKED`, `GRANT_DELETED`, `GRANT_PAUSED`, `DEFAULT_UPDATE` — reflect the link state in your system.
- Call `/grant/remove` when a user unlinks in your app, and handle the OTP-verification branch.
- Run the whole flow on `https://sandbox.bankhub.dev` first; switch to `https://production.bankhub.dev` together with the production secrets.

## Before going to production

Verify against the **entire** production checklist: https://cas.so/en/launch-checklist.md

For every checklist item, point at the code (file path + line) that proves it is handled, or state why it does not apply. Never tick an item without evidence.

## Other Cas skills

Full catalogue (use it to add more Cas products later):

https://cas.so/en/skills/index.json
