# PayNow for Unified Payments API To accept PayNow payments, you must follow these steps: 1. [Request a payment](#Request_a_payment). 2. [Display the QR code](#Display_the_QR_code). ## Request a payment To send a payment request, call the [Request a payment](https://api-reference.checkout.com/tag/Payments/#operation/requestAPaymentOrPayout) endpoint: > **Information** > > Your base URL's `{prefix}` value is unique to your account and environment. To learn how to retrieve your base URLs for the sandbox and production environments, see [API endpoints](https://www.checkout.com/docs/developer-resources/api/api-endpoints.md). **Production** `POST` `https://{prefix}.api.checkout.com/payments` **Sandbox** `POST` `https://{prefix}.api.sandbox.checkout.com/payments` ### Request example ```json { "source": { "type": "paynow" }, "currency": "SGD", "amount": 1000, "processing_channel_id": "pc_leqnrrvqzt6ulfoiososbhmyi4" } ``` ### Response example If you receive a `202 Accepted` response with a payment `id` value and the `status` field set to `Pending`, your request was successful. ```json { "id": "pay_wwfb2jkxfwvu7ebiincw3ibbmi", "status": "Pending", "payment_type": "Regular", "_links": { "self": { "href": "https://{prefix}.api.sandbox.checkout.com/payments/pay_wwfb2jkxfwvu7ebiincw3ibbmi" }, "redirect": { "qr_code": { "image": "", "text": "00020126570009SG.PAYNOW01012000Singapore62200116pn_71f6dfc1763b4" } } } } ``` --- ## Display the QR code 1. Take the URL from the `redirect.qr_code.text` field and convert it into a QR code using a third-party QR code generator tool. 2. Display the QR code to the customer. 3. The customer must scan the QR code using their online banking app, and confirm the transaction. > **Information** > > The QR code is valid for five days. The payment expires if the customer does not authorize the payment within this time frame. Checkout.com communicates the capture of the payment using webhooks. When you receive a `payment_captured` webhook, it indicates that the transaction has been successfully completed. PayNow only supports auto-capture payments. > **Information** > > You cannot void an auto-captured payment. To reverse a payment in progress, wait for the payment to be captured, and then process a refund. --- ## Get details about a payment To retrieve details about the payment, call the [Get payment details](https://api-reference.checkout.com/tag/Payments/#operation/getPaymentsList) endpoint, setting the `payment_id` value from the payment response as the `{id}` path parameter: **Live** `GET` `https://{prefix}.api.checkout.com/payments/{id}` **Sandbox** `GET` `https://{prefix}.api.sandbox.checkout.com/payments/{id}` See [Get payment details](https://www.checkout.com/docs/payments/manage-payments/get-payment-details) for more information. --- ## Refund a payment PayNow supports both partial and full refunds. You can refund the payment through the [Dashboard](https://dashboard.checkout.com) or by calling the [Refund a payment](https://api-reference.checkout.com/tag/Payments/#operation/refundAPayment) endpoint, setting the `payment_id` value from the payment response as the `{id}` path parameter: **Live** `POST` `https://{prefix}.api.checkout.com/payments/{id}/refunds` **Sandbox** `POST` `https://{prefix}.api.sandbox.checkout.com/payments/{id}/refunds` ### Request example ```json { "source": { "type": "paynow" }, "amount": 1000 } ``` ### Response example ```json { "action_id": "act_3rm4qg75lthuniecyz2cob66fy", "_links": { "payment": { "href": "https://{prefix}.api.sandbox.checkout.com/payments/pay_wwfb2jkxfwvu7ebiincw3ibbmi" } } } ``` ## Test your integration To simulate a successful payment, send a payment request to the sandbox environment as shown in the [Request a payment](#Request_a_payment) section. ### Test a rejected payment To simulate a rejected payment, send a payment request to the sandbox environment as shown in the [Request a payment](#Request_a_payment) section, with the `amount` field set to either _2200_ or _3000_: #### Request example ```json { "source": { "type": "paynow" }, "currency": "SGD", "amount": 2200, "processing_channel_id": "pc_leqnrrvqzt6ulfoiososbhmyi4" } ``` #### Response example ```json { "id": "pay_ivojsutjd2re7dfzvexvkrk57a", "action_id": "act_jzojav7lcqluxfi7dhwuc3aotm", "amount": 2200, "currency": "SGD", "approved": false, "status": "Declined", "response_code": "20068", "response_summary": "Internal error", "risk": { "flagged": false }, "processed_on": "2025-06-05T10:16:36.0977814Z", "_links": { "self": { "href": "https://{prefix}.api.sandbox.checkout.com/payments/pay_ivojsutjd2re7dfzvexvkrk57a" }, "actions": { "href": "https://{prefix}.api.sandbox.checkout.com/payments/pay_ivojsutjd2re7dfzvexvkrk57a/actions" } } } ``` ### Test an expired payment To simulate an expired payment, send a payment request to the sandbox environment as shown in the [Request a payment](#Request_a_payment) section, with the `amount` field set to _4000_: #### Test a refund To simulate a refund, send a refund request to the sandbox environment as shown in the [Refund a payment](#Refund_a_payment) section, with the `amount` field set to: - Any even number for a successful refund - Any odd number for a rejected refund