Charges API
The Charges API lets you build your own checkout and have Beam process the payment. You control the interface, so you decide what the shopper sees at every step.
The following operations are available:
- Create Charge (
POST /api/v1/charges): start a payment. - Get Charge by ID (
GET /api/v1/charges/{chargeId}): read the current status of one charge. - List Charges (
GET /api/v1/charges): list past charges, with filters.
A charge cannot be edited or deleted after it is created. To reverse a successful charge, create a refund.
POST /api/v1/charges is not the only call that creates a charge.
Capturing a card authorization creates one too, and returns
its chargeId. Those charges also have source API, and you read and track them with the same endpoints on this
page.
This page covers the request and response shapes. For the concepts behind them, see Charges: the charge flow, the available payment methods, the lifecycle and statuses, and how to track the outcome. For the full schema, see the Charges API Specification. For a walkthrough of a first payment, see the Integration Guide.
Create a charge
The amount field is in the smallest currency unit. For Thai Baht (THB) that is satang, so 10000 means 100.00 THB.
For how to build the Authorization header, see Authentication.
Card charge
POST https://api.beamcheckout.com/api/v1/charges
Content-Type: application/json
Authorization: Basic <base64(merchantId:apiKey)>
{
"amount": 10000,
"currency": "THB",
"paymentMethod": {
"card": {
"cardHolderName": "CARDHOLDER NAME",
"expiryMonth": 12,
"expiryYear": 30,
"pan": "4111111111111111",
"securityCode": "123"
},
"paymentMethodType": "CARD"
},
"referenceId": "order_190821",
"returnUrl": "https://www.beamcheckout.com",
"skip3dsFlow": false
}If Beam has enabled 3DS bypass for your account, set skip3dsFlow to true to skip 3DS. This works on the card
payment methods: CARD, CARD_INSTALLMENTS, CARD_TOKEN, and CARD_TOKEN_INSTALLMENTS. See
Bypassing 3DS.
Sending raw card numbers to your own server brings it into PCI DSS scope. Use
Card Tokenization to exchange card details for a token in the shopper’s browser, then
charge the token with CARD_TOKEN.
QR PromptPay charge
This same request is also how shoppers pay with Alipay. The shopper scans the returned QR code from inside their Alipay app to complete payment.
POST https://api.beamcheckout.com/api/v1/charges
Content-Type: application/json
Authorization: Basic <base64(merchantId:apiKey)>
{
"amount": 10000,
"currency": "THB",
"paymentMethod": {
"qrPromptPay": {
"expiryTime": "2023-12-31T23:59:59Z"
},
"paymentMethodType": "QR_PROMPT_PAY"
},
"referenceId": "order_190822",
"returnUrl": "https://www.beamcheckout.com",
"skip3dsFlow": false
}Mobile banking charge
The example below uses Krungsri App. Swap paymentMethodType and its object for the app you want.
POST https://api.beamcheckout.com/api/v1/charges
Content-Type: application/json
Authorization: Basic <base64(merchantId:apiKey)>
{
"amount": 10000,
"currency": "THB",
"paymentMethod": {
"krungsri": {},
"paymentMethodType": "KRUNGSRI_APP"
},
"deviceType": "ANDROID",
"referenceId": "order_190823",
"returnUrl": "https://www.beamcheckout.com"
}Each app has its own paymentMethodType and its own object, which is empty:
| App | paymentMethodType | Object |
|---|---|---|
| Krungsri App | KRUNGSRI_APP | "krungsri": {} |
| Bangkok Bank App | BANGKOK_BANK_APP | "bbl": {} |
| KPlus | KPLUS | "kPlus": {} |
| Make | MAKE | "make": {} |
| SCB Easy | SCB_EASY | "scbEasy": {} |
Mobile banking apps need a mobile device, so send deviceType as ANDROID or IOS. If you leave it out it defaults
to WEB, and the payment is unlikely to complete.
Optional fields
deviceType: the shopper’s device, one ofANDROID,IOS, orWEB. Defaults toWEB. Send the accurate value, because it raises the chance of the payment completing, and the mobile banking apps need a mobile device.referenceId: your own order reference. You can filter charges by it later.customer.billingAddress: the billing address for a card charge. Optional, but recommended, because card issuers check it (for example, AVS), so a full address raises approval rates.
For every field, see CreateChargeRequest.
Handle the charge creation response
The charge is created as soon as the call succeeds, but some payment methods need one more step from the shopper. The
actionRequired field tells you which:
actionRequired | What it means | What you do |
|---|---|---|
NONE | Nothing more is needed from the shopper. | Wait for the charge to reach a final status. |
REDIRECT | The shopper has to finish the payment on another page. The URL is in the redirect object. | Send the shopper to redirect.redirectUrl. |
ENCODED_IMAGE | The shopper has to scan a QR code. The image is in the encodedImage object. | Decode imageBase64Encoded and show the image to the shopper. |
No action required
{
"actionRequired": "NONE",
"chargeId": "ch_2xTsz7Qit55pahSvKfJG3UMkpFQ",
"paymentMethodType": "CARD"
}Redirect required
{
"actionRequired": "REDIRECT",
"chargeId": "ch_2xTsz7Qit55pahSvKfJG3UMkpFQ",
"redirect": {
"redirectUrl": "https://www.beamcheckout.com/redirect"
},
"paymentMethodType": "CARD"
}Encoded image required
{
"actionRequired": "ENCODED_IMAGE",
"chargeId": "ch_2xTsz7Qit55pahSvKfJG3UMkpFQ",
"encodedImage": {
"expiry": "2025-08-24T14:15:22Z",
"imageBase64Encoded": "iVBORw0KGgoAAAANSUhEUgAAAQAAAAEAAQMAAABmvDolAAAABlBMVEX///8AAABVwtN+AAABXUlEQVR42uyYsbHzIBCEjyEgpASVQmsujVJUAiGBhv1nD5iR/VvvxY9jAwfyF91wuwuytbW19ZOgunwNNZRY4nn0L6+1gMYff/kqoUYQOPklmQMcx3SJBNRYYpGDo8pWAQ8QEDEOcE4iETgXBfpeEAgo8rg4qwNG3P5XYMijhqoH5iEdVweaQ/MAjbJK7HmRcsJrLQBA0zSoA9CtyG8tyALQXHPqk1VENBXf/7cCCAGuBWsSfVKOMwHZGuDQel0MNQAoBy0i3XJzDUCcpgETgDZY2A6y3PzBCOBaR1iTtA2qP9zPgw1A66L4a9ZFfBqlEUBmXeTeFEWQ74NaCGALojn0WDyQkzngrRWL3g4IPNTmdYH5SMJc5HkZg7IHzFvzqIu6ON8ei5YA+ptYib0eyP9zMAN0myxHN8qPvDAAjLyYgTHqolgDpk/SHxTQ4/LlFeVvA1tbWxb1LwAA//8XPln5fRCHxAAAAABJRU5ErkJggg==",
"rawData": "Sample QR Code for payment"
},
"paymentMethodType": "QR_PROMPT_PAY"
}Get a charge
Use the chargeId from the creation response to read one charge:
GET https://api.beamcheckout.com/api/v1/charges/{chargeId}
Authorization: Basic <base64(merchantId:apiKey)>The response holds the current status, and failureCode when the charge failed. See
Charge failure codes.
Polling this endpoint is the fallback way to learn the outcome. Webhooks are the recommended way, so see Track the charge before you build a polling loop.
List charges
GET /api/v1/charges lists the charges on your merchant account, most recent first. Query parameters filter the
results: referenceId, source_in, sourceId, plus offset and limit for paging.
To find the charges for one payment link, filter by source_in=PAYMENT_LINK and sourceId={paymentLinkId}:
GET https://api.beamcheckout.com/api/v1/charges?source_in=PAYMENT_LINK&sourceId={paymentLinkId}
Authorization: Basic <base64(merchantId:apiKey)>A payment link can have several charge attempts. The link is paid only when one of its charges has status
SUCCEEDED.
To find the charges for one card authorization, use the authorization’s own endpoint:
GET https://api.beamcheckout.com/api/v1/card-authorizations/{cardAuthorizationId}/charges
Authorization: Basic <base64(merchantId:apiKey)>A card authorization can have several charges, one per capture. See Capture API.
Errors
A failed payment still returns HTTP 2xx, because Beam accepted your request. HTTP 4xx and 5xx responses mean the request itself was rejected. See Error Handling, and use idempotency keys so a retried create call cannot charge the shopper twice.