--- url: 'https://acquirer-api-docs-v4-en.pingpongx.com/en/notes/integrate/link/index.md' description: >- Explain the Redirect Checkout integration flow for merchants that want to go live quickly and let shoppers complete payment on a PingPong-hosted checkout page. --- PingPong Checkout is an efficient, low-code checkout solution designed for global businesses. It helps merchants launch quickly with a secure, compliant, and conversion-oriented payment experience while minimizing integration cost. Recommended scenario: merchants that want to launch payment quickly and use a redirect-hosted model, where the shopper is redirected to a PingPong secure payment page to complete checkout. ::: tip Best for This path is ideal for teams that want the fastest launch path and accept that shoppers leave the merchant site to finish payment on a PingPong-hosted page. If you want the checkout to stay inside your site or app, choose the [Embedded SDK](/en/notes/integrate/sdk-v4/). ::: ## Payment Flow ```mermaid %%{init: { 'theme': 'base', 'themeVariables': { 'primaryColor': '#E3F2FD', 'primaryTextColor': '#0D47A1', 'primaryBorderColor': '#1976D2', 'lineColor': '#1565C0', 'secondaryColor': '#BBDEFB', 'tertiaryColor': '#90CAF9', 'background': '#F8FBFF', 'mainBkg': '#E3F2FD', 'secondBkg': '#BBDEFB', 'tertiaryBkg': '#90CAF9', 'actorBkg': '#2196F3', 'actorBorder': '#1976D2', 'actorTextColor': '#FFFFFF', 'actorLineColor': '#1565C0', 'signalColor': '#0D47A1', 'signalTextColor': '#0D47A1', 'c0': '#E8F4FD', 'c1': '#D1E7DD', 'c2': '#B3D9FF', 'c3': '#81C784', 'noteBkgColor': '#E1F5FE', 'noteTextColor': '#01579B', 'noteBorderColor': '#0288D1', 'loopTextColor': '#0D47A1', 'activationBkgColor': '#B3E5FC', 'activationBorderColor': '#0277BD' } }}%% sequenceDiagram participant Client as 💻 Client participant Merchant as 🏪 Merchant Server participant PP as 🔄 PingPong Server participant Checkout as 🛒 PingPong Checkout participant Bank as 🏦 Issuer Note over Client, Merchant: 📦 Session creation Client->>Merchant: 1. Submit order and start payment Merchant->>PP: 2. Call prePay (reserve) PP-->>Merchant: 3. Return paymentUrl Merchant-->>Client: 4. Return paymentUrl Note over Client, Bank: 🛒 Checkout payment Client->>Checkout: 5. Redirect to PingPong Checkout Checkout->>PP: 6. Initialize session and load payment methods PP-->>Checkout: 7. Return available payment methods Client->>Checkout: 8. Choose a payment method and confirm payment Checkout->>PP: 9. Submit payment request alt Payment succeeds PP-->>Checkout: 10. Return success result Checkout-->>Client: 11. Show result page and return to merchant based on configuration else 3DS challenge required PP->>Bank: 12. Start 3D Secure challenge Bank-->>Client: 13. Shopper completes verification Bank-->>PP: 14. Return challenge result PP-->>Checkout: 15. Return final payment result Checkout-->>Client: 16. Show result page and return to merchant based on configuration else Payment fails PP-->>Checkout: 17. Return failure result Checkout-->>Client: 18. Show failure page or guide the shopper to retry end Note over Merchant, PP: 📡 Notification and confirmation PP->>Merchant: 19. Push payment notification Merchant->>Merchant: 20. Update order status Merchant-->>PP: 21. Return HTTP 200 ``` Flow summary: 1. The shopper submits the order and starts payment on the merchant site. 2. The merchant server calls [prePay (reserve)](/en/notes/checkout/api/reserve/) to create the checkout payment session. 3. PingPong Checkout returns `paymentUrl`, `transactionId`, and related session information. 4. The merchant server returns `paymentUrl` to the front end, and the front end redirects the shopper to PingPong Checkout. 5. The shopper selects a payment method and completes payment on the PingPong-hosted checkout. If 3D Secure is required, PingPong Checkout guides the shopper through the challenge. 6. After payment, PingPong Checkout pushes the final result through `notificationUrl`. 7. If the merchant does not receive the asynchronous notification in time, or needs to verify the result immediately after the shopper returns, it should actively call [Transaction Query](/en/notes/checkout/api/getOne/). ::: warning Note Seeing the checkout result page or returning to the merchant result page only means the front-end flow has ended. It does not guarantee that the order is successfully paid. Fulfillment, settlement, or entitlement delivery must rely on the server-side notification or transaction query result. ::: ## API List Redirect Checkout usually involves the following APIs and notifications: | Phase | Type | Document | Required | Purpose | |:---|:---|:---|:---:|:---| | Payment creation | API | [prePay (reserve)](/en/notes/checkout/api/reserve/) | Required | Create the hosted checkout session and get `paymentUrl` | | Payment result | Notification | [Payment Notification](/en/notes/notify/payment/notify/) | Required | Receive the final payment result and update the merchant order | | Payment result | API | [Transaction Query](/en/notes/checkout/api/getOne/) | Recommended | Actively verify the transaction status when notifications are delayed, missing, or need fallback confirmation | | Capture | API | [Authorization Capture](/en/notes/checkout/api/modifications/capture/) | As needed | Capture an authorized transaction when manual capture is used | | Capture | Notification | [Capture Notification](/en/notes/notify/status/captureNotify/) | As needed | Receive the result of a manual capture | | Capture | API | [Capture Query](/en/notes/checkout/api/getCapture/) | Recommended | Confirm capture status when the notification is delayed or during reconciliation | | Refund | API | [Refund Request](/en/notes/checkout/api/modifications/refund/) | As needed | Refund a successful payment | | Refund | Notification | [Refund Notification](/en/notes/notify/refundNotify/) | As needed | Receive the refund result and update the refund status | | Refund | API | [Refund Query](/en/notes/checkout/api/getRefund/) | Recommended | Confirm refund status when notifications are delayed or during reconciliation | ## Integration Preparation Before you start development, make sure the following items are ready. | Item | Description | |:---|:---| | Account information | `clientId` and `accId` have been obtained, and the shop can transact normally | | Payment methods | The payment methods to be shown in checkout are enabled, and their supported countries, currencies, amount ranges, and refund capability have been confirmed | | Signing capability | Request signing has been completed according to the [Signature Guide](/en/notes/guide/sign/), and all request parameters participate in signing | | Signature verification capability | The merchant can verify the `sign` in PingPong Checkout responses and asynchronous notifications | | Notification URL | A public `notificationUrl` is ready for asynchronous payment result notifications | | Result page URL | `payResultUrl` is ready for the shopper to return to the merchant page after payment | | Order status handling | The merchant system stores `merchantTransactionId`, `transactionId`, and order status, and supports idempotent updates | | Front-end redirect capability | Web, WAP, or app scenarios can open `paymentUrl` correctly and have completed compatibility validation | ::: warning Note `notificationUrl` must be a complete public URL. Do not use `localhost`, `127.0.0.1`, or an internal IP, and do not append query parameters to the URL. ::: ## Integration Steps Complete the integration in the following steps: 1. [Step 1: Create the payment session](#step-1-create-the-payment-session) 2. [Step 2: Redirect to PingPong Checkout](#step-2-redirect-to-pingpong-checkout) 3. [Step 3: Shopper completes payment](#step-3-shopper-completes-payment) 4. [Step 4: Get the final payment result](#step-4-get-the-final-payment-result) ### Step 1: Create the payment session After the shopper confirms the order on the merchant site, the merchant server calls [prePay (reserve)](/en/notes/checkout/api/reserve/) to create the payment session. Do not call this API directly from the browser or app client, to avoid exposing signing secrets. Payment request key parameters: | Parameter | Required | Description | |:---|:---:|:---| | `captureDelayHours` | O | Capture mode. Automatic capture is the default. If manual capture is needed, configure it according to payment method capability and API rules | | `amount` | M | Transaction amount | | `currency` | M | ISO 4217 three-letter transaction currency | | `merchantTransactionId` | M | Merchant order ID, unique order identifier | | `shopperIP` | M | Shopper IP | | `merchantUserId` | M | Merchant-side unique user ID | | `goods` | M | Goods information, including at least product name, unit price, and quantity | | `customer` | C | Shopper information. Different payment methods may require email, phone number, or billing details | | `paymentMethods` | O | Restrict which payment methods can be shown in checkout. If omitted or empty, the shop configuration is used | | `notificationUrl` | O | Payment result notification URL. Strongly recommended | | `closeNotificationUrl` | O | Close-order notification URL. When provided, you can receive active or passive order close notifications | | `payResultUrl` | O | Merchant result page URL after the shopper completes payment | | `language` | O | Checkout display language. English is used by default when not provided. See [Language Codes](/en/notes/appendix/languageCode/) | For full parameter details, see [prePay (reserve)](/en/notes/checkout/api/reserve/). Payment request example (`bizContent` only): ```json { "captureDelayHours": "0", "amount": "100", "currency": "USD", "merchantTransactionId": "{{merchantTransactionId}}", "payResultUrl": "https://test-acquirerpay.pingpongx.com/qa/result.html", "notificationUrl": "https://test-acquirerpay.pingpongx.com/qa/result.html", "closeNotificationUrl": "https://test-acquirerpay.pingpongx.com/qa/close-result.html", "language": "en", "shopperIP": "222.126.52.23", "merchantUserId": "USER_12345", "customer": { "email": "buyer@gmail.com" }, "paymentMethods": [], "goods": [ { "name": "Sample product", "description": "Sample description", "unitPrice": "1", "number": "1", "virtualProduct": "Y", "imgUrl": "https://xiu.mepsking.top/material/1/16606169805015585.png" } ] } ``` Payment response example (`bizContent` only): ```json { "amount": "100", "paymentUrl": "https://sandbox-safepay.pingpongx.com?token=EU:example", "transactionId": "26070600000751051115", "token": "EU:example", "merchantTransactionId": "PMT-A1XGH96WNE1783303688835", "currency": "USD", "innerJsUrl": "https://payssr-cdn.pingpongx.com/production-fra/acquirer-checkout-web/sandbox/pp-checkout.js?token=EU:example" } ``` Key response fields: | Parameter | Description | |:---|:---| | `transactionId` | PingPong transaction ID for later query, refund, and reconciliation | | `merchantTransactionId` | Merchant order ID | | `paymentUrl` | Hosted checkout URL used in redirect mode | | `token` | Checkout token, used by embedded SDK and other checkout capabilities | | `innerJsUrl` | JavaScript SDK URL, used by embedded checkout scenarios | ### Step 2: Redirect to PingPong Checkout After the merchant server gets `paymentUrl`, return it to the front end. The front end should redirect using the complete URL returned by PingPong Checkout. Do not append extra parameters or replace the domain or path. The following examples show how the merchant front end opens `paymentUrl`: ::: tabs @tab Web ```js function redirectOnWeb(paymentUrl) { if (!paymentUrl) return; window.location.assign(paymentUrl); } ``` @tab WAP ```js function redirectOnWap(paymentUrl) { if (!paymentUrl) return; window.location.href = paymentUrl; } ``` @tab App (iOS) ```swift guard let url = URL(string: paymentUrl) else { return } UIApplication.shared.open(url, options: [:]) { success in if !success { // Guide the shopper to retry or use another payment method } } ``` @tab App (Android) ```kotlin try { val intent = Intent(Intent.ACTION_VIEW, Uri.parse(paymentUrl)) intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) startActivity(intent) } catch (e: Exception) { e.printStackTrace() } ``` ::: ::: warning Redirect notes - `paymentUrl` is tied to a payment session and should be returned to the shopper promptly after order creation. - In app scenarios, we recommend using the system browser, Custom Tabs, or SFSafariViewController first. If you must use a WebView, complete real-device validation in advance. - Do not save or expose `paymentUrl` as proof of payment to anyone other than the current shopper. ::: ### Step 3: Shopper completes payment After entering PingPong Checkout, the shopper selects a payment method, provides the required information, and confirms payment. If 3D Secure is required, PingPong Checkout guides the shopper through the verification within the hosted flow. The checkout display language is controlled by `bizContent.language`. If `language` is not provided, English is used by default. If it is provided, PingPong Checkout uses the passed value. See [Language Codes](/en/notes/appendix/languageCode/) for supported values. After payment, PingPong Checkout shows the result page first and then returns the shopper to the merchant result page according to configuration. Merchants can also configure the post-payment redirect behavior in the PingPong Checkout Dashboard. ### Step 4: Get the final payment result For Redirect Checkout, the final payment result should be confirmed through server-side asynchronous notification first. If the notification is delayed, not delivered, or the merchant needs immediate verification after the shopper returns, actively call [Transaction Query](/en/notes/checkout/api/getOne/). Payment notification example: ```json { "clientId": "2023121216311410287", "code": "000000", "bizContent": "{\"exchangedCurrency\":\"USD\",\"amount\":\"100.000000\",\"transactionTime\":\"1783303837000\",\"transactionId\":\"26070600000751051115\",\"notifyType\":\"RECHARGE\",\"transactionEndTime\":\"1783303856604\",\"requestId\":\"aaa364ab-c811-47b6-899d-92a4de8189be\",\"merchantTransactionId\":\"PMT-A1XGH96WNE1783303688835\",\"paymentMethod\":{\"type\":\"Alipay\"},\"currency\":\"USD\",\"exchangedAmount\":\"100.000000\",\"captureDelayHours\":0,\"status\":\"SUCCESS\"}", "sign": "A9383DCF4FF42C07423C2BDD77490622AA08DF9155D125683BA8BB794C24CCEC", "accId": "2023121216311410287522", "description": "Transaction succeeded", "signType": "SHA256" } ``` Key notification fields: | Parameter | Description | Handling recommendation | |:---|:---|:---| | `notifyType` | Notification type. Payment notification is always `RECHARGE` | Identify the event type | | `transactionId` | PingPong transaction ID | Save for later query, refund, and reconciliation | | `merchantTransactionId` | Merchant order ID | Locate the merchant order | | `amount` / `currency` | Transaction amount and currency | Must be checked against the merchant order | | `status` | Final payment result | Update the merchant order according to the status | Recommended handling for notification `status`: | `status` | Handling recommendation | |:---|:---| | `SUCCESS` | Payment succeeded. The merchant can fulfill the order or grant entitlements | | `FAILED` | Payment failed. Keep the order unpaid or failed, and allow the shopper to retry | | `CANCEL` | Rejected by risk control. Do not treat the order as successful | | `CLOSED` | The order has been closed. This notification is sent only when a close-order notification URL is provided | After receiving the notification, you do not need to sign the response. However, regardless of whether the payment succeeded, you must always return the following fixed response format. The merchant server should return HTTP `2xx` first to acknowledge receipt. Notification response example: ```http HTTP/1.1 200 OK Content-Type: text/plain; charset=UTF-8 Content-Length: 2 OK ``` ## After Payment ### Transaction Query When the shopper returns from checkout to the merchant result page, the notification is delayed, notification handling fails, or the merchant needs to run a compensation task, call [Transaction Query](/en/notes/checkout/api/getOne/) to get the latest transaction status. Prefer using the stored `merchantTransactionId` or PingPong `transactionId` to locate the transaction. A successful query request only means that the query API succeeded; it does not mean the payment succeeded. The merchant order status should follow the transaction status in the query response. ### Capture By default, PingPong Checkout completes capture automatically according to the payment request and payment method capability. If your business uses authorization first and capture later, configure manual capture when creating the payment session and then call [Authorization Capture](/en/notes/checkout/api/modifications/capture/) after the transaction reaches a capturable state. ### Refund After payment succeeds, if the shopper requests a refund, the merchant cancels a paid order, or some or all funds need to be returned, call [Refund Request](/en/notes/checkout/api/modifications/refund/) on the original transaction. The refund result can be confirmed through [Refund Notification](/en/notes/notify/refundNotify/) or, when notifications are delayed or reconciliation is needed, through [Refund Query](/en/notes/checkout/api/getRefund/). ### Reconciliation To understand statement generation rules and settlement cycles, refer to [Settlement Cycle and Reconciliation Statement](/en/notes/reconciliation/settlementCycle/). If you need statement download capability, refer to [SFTP Service Application](/en/notes/reconciliation/transactionStatementDownload/).