Terminal Integration
This page shows the server-side steps. Read the overview first.
Before you start
Confirm the following with Ops or your account manager:
- An Account, Merchant, and at least one Location and Terminal exist.
- At least one Reader is approved for that Terminal.
- You hold an API key.
Collect a payment
Choose a Reader. List the Readers approved for the Terminal. Choose one with
statusACTIVEandconnection_statusonline.bashcurl "https://bn.cake.vn/api/terminal/readers?status=ACTIVE" \ -H "Bn-Api-Key: $BN_SECRET_KEY"A public endpoint for listing Readers by Terminal is on the roadmap. Today, contact your account manager to confirm which Readers are approved for a given Terminal.
Create a PaymentIntent. Do not set
confirm. The PaymentIntent must be inrequires_payment_method.Send it to the Reader.
bashcurl -X POST "https://bn.cake.vn/api/terminal/readers/$READER_ID/process_payment_intent" \ -H "Bn-Api-Key: $BN_SECRET_KEY" \ -H "Content-Type: application/json" \ -d '{ "payment_intent_id": "YOUR_PAYMENT_INTENT_ID", "process_config": { "enable_customer_cancellation": true } }'The response returns a
reader_actionwith statusin_progress. This response confirms that the Reader received the action. It does not confirm the payment.Read the result. Listen for the webhooks in the next section. As a fallback, retrieve the PaymentIntent.
Webhooks
Track the payment with the PaymentIntent events. They are the same as for online payments.
| Event | Description |
|---|---|
payment_intent.status.succeeded | The payment is complete. |
payment_intent.status.requires_payment_method | The payment was declined. Send the PaymentIntent to the Reader again. |
payment_intent.status.canceled | The PaymentIntent was canceled. |
To track the Reader itself, use the reader action events.
| Event | Description |
|---|---|
reader_action.status.succeeded | Bahn authorized the payment. |
reader_action.status.failed | The payment was declined, timed out, or the Reader lost its connection. Read failure_code, failure_message, and failure_decline_code. |
reader_action.status.canceled | You or the customer canceled the action. |
See Events for the full payloads.
Decline and retry
After a decline, the PaymentIntent returns to requires_payment_method. Send the same PaymentIntent to the Reader again. Do not create a new PaymentIntent. Do not parse message. Use code and decline_code. The code comes from the PaymentIntent last_payment_error, for example card_declined, insufficient_funds, expired_card, or processing_error.
Cancel an action
curl -X POST "https://bn.cake.vn/api/terminal/readers/$READER_ID/cancel_action" \
-H "Bn-Api-Key: $BN_SECRET_KEY"Bahn accepts this call while the payment is in authorization. Check the PaymentIntent status before you finish the sale. Set enable_customer_cancellation to true to let the customer cancel on the Reader.
Errors
| Error code | Type | HTTP status | Cause | Action |
|---|---|---|---|---|
terminal_reader_busy | api_error | 500 | The Reader already runs an action. | Wait until the action ends. Or call cancel_action. |
terminal_reader_timeout | api_error | 500 | The Reader did not answer in time. | Retry the request. |
intent_invalid_state | invalid_request_error | 400 | The PaymentIntent is not in requires_payment_method. | Create a new PaymentIntent. |
resource_missing | invalid_request_error | 400 | The Reader has no action in progress. | Check the Reader before you cancel. |
Bahn sets the HTTP status from the error type: card_error and invalid_request_error return 400, authentication_error returns 401, idempotency_error returns 409, rate_limit_error returns 429, and api_error returns 500.
If the Reader stays in_progress after it lost its connection, call cancel_action to reset it.
Manage Readers
| Task | Request |
|---|---|
| List | GET /api/terminal/readers |
| Retrieve | GET /api/terminal/readers/{id} |
| Rename | POST /api/terminal/readers/{id} with label |
| Delete | DELETE /api/terminal/readers/{id} |
A Reader has one of these statuses: ACTIVE, BLOCKED, COMPROMISED, or REVOKED. A Reader leaves ACTIVE in one direction only. To use the device again, approve it as a new Reader. Deleting a Reader sets it to REVOKED. Its past payments stay on record.
Next step
Act for a connected merchant if you build a platform. Otherwise, see the reference.