Skip to main content

Card Payment Callback — App Integration Guide

Configure where users are redirected after credit card payment completes.


Redirect URL Configuration

Format

After payment, we redirect users to:

{callback}/thankyou?orderId={orderId}&status={status}&amount={amount}
Query paramDescription
orderIdYour order ID
statussuccess or failure
amountOrder grand total

How to Set the Redirect Base URL

Pass the optional callback parameter when calling POST /cardpayment. We store it and use it when building the redirect URL.

callback valueRedirect target
yourapp://paymentsyourapp://payments/thankyou?orderId=...&status=...&amount=...
https://app.yourdomain.comhttps://app.yourdomain.com/thankyou?orderId=...&status=...&amount=...
(omitted or invalid)https://shop.villamarket.com/thankyou?orderId=...&status=...&amount=...

Rules

  • Provide only the base URL (e.g. yourapp://payments). We append /thankyou and the query string.
  • Trailing slashes are stripped.
  • If callback is missing or invalid, we use https://shop.villamarket.com.

Passing callback at POST /cardpayment

Endpoint: POST /cardpayment
Content-Type: application/x-www-form-urlencoded

Dev: https://shop.villamarket.com/api/payment3devapi/cardpayment
Prod: https://shop.villamarket.com/api/payment3/cardpayment

Optional form field:

ParameterTypeDescription
callbackstringBase URL for the redirect. Omit to use https://shop.villamarket.com.
bypass_order1/trueBypass order verification at cardpayment and callback; use body/record values only.

Example (form body):

token=tokn_xxx&userId=usr_123&orderId=482500007436&basketId=basket_456&customerId=cust_789&grandTotal=1500.00&mid=401012234152001&callback=yourapp://payments

In the KBank form (hidden input):

const callbackInput = document.createElement("input");
callbackInput.type = "hidden";
callbackInput.name = "callback";
callbackInput.value = "yourapp://payments"; // or "https://app.yourdomain.com"
form.appendChild(callbackInput);

Flow Overview

KBank invokes our callback with a fixed payload — we cannot add parameters. The redirect base comes from the payment record, which we populate from callback when you call POST /cardpayment.

┌─────────────┐     POST /cardpayment          ┌──────────────┐     ┌─────────────┐
│ Your App │ ──────────────────────────────▶│ CardToken │────▶│ KBank │
│ │ body: ..., callback=yourapp:// │ Lambda │ │ Charge │
└─────────────┘ └──────────────┘ └─────────────┘
│ │ │
│ │ Stores callback │
│ │ in CardPaymentRecord │
│ │ │
│ │ │ 3DS
│ │ ▼
│ │ ┌──────────────┐
│ │ │ KBank │
│ │◀─────────────│ Callback │
│ │ (no custom │ (fixed body)│
│ │ params) └──────────────┘
│ │
│ │ Reads callback from
│ │ CardPaymentRecord
│ │
│◀──────────────────────────────────────────────┤
│ HTML redirect to yourapp://payments/thankyou?orderId=...&status=...&amount=...

iOS / Android (custom URL scheme):

myapp://payments/thankyou?orderId=482500007436&status=success&amount=1500.00

Use callback=myapp://payments in the /cardpayment request.

Universal Links (iOS) / App Links (Android):

https://app.yourdomain.com/thankyou?orderId=482500007436&status=success&amount=1500.00

Use callback=https://app.yourdomain.com in the /cardpayment request.


Bypass order

Pass bypass_order=1 (or bypass_order=true) at POST /cardpayment to skip order verification at both stages:

  1. Cardpayment — Skips OrderTable lookup; uses orderId and grandTotal from the request body. No real order required.
  2. Callback — Skips OrderTable lookup; redirects using values from the payment record.

Use for testing redirect flows without a real order in the system.


Notes

  • Handle the deep link in your app and read orderId, status, and amount from the query string.
  • For 3D Secure flows, the redirect happens in a web view; register your scheme so the web view can hand off to your app.