Skip to main content

Introduction

Boxo Payments is an in-app payment functionality that enables host app users to complete payments for orders within the miniapp.
Here is a diagram illustrating the payment process for a miniapp order using the host app’s payment system.AuthDiagram
1

User initiates payment

The user navigates to the payment page in the miniapp and initiates the creation of an order.
2

Miniapp creates order request

The miniapp server creates the order and sends a createOrderPayment request to the Boxo Platform.
3

Platform initiates payment process

The Boxo Platform initiates the order payment process on the host app server.
4

Host app returns payment ID

The host app server returns an orderPaymentID to the Boxo Platform.
5

Platform forwards payment ID

The Boxo Platform then forwards the orderPaymentID to the miniapp server.
6

Miniapp receives payment ID

The miniapp server passes the orderPaymentID to the miniapp.
7

SDK receives payment request

The miniapp forwards the orderPaymentID to the Boxo JS SDK’s pay method.
8

Native SDK displays confirmation

The Boxo Native SDK captures the Boxo JS SDK’s pay event (with the orderPaymentID) and displays a payment confirmation page to the user.
9

User confirms payment

The user confirms the payment.
10

Host app processes payment

The host app processes the payment and sends the payment status as a response to the Boxo JS SDK pay event.
  • During this process, the host app server sends a callback to the Boxo Platform, which updates the order status in the miniapp backend.
11

Miniapp processes payment status

The miniapp processes the payment status received from the Boxo JS SDK event and confirms the order payment status on its server.
12

Payment status finalized

The miniapp finalizes the order payment status.
  • If the order is still processing at this stage, the miniapp will request the payment status from the Boxo Platform, which, in turn, will query the host app server for an update.
13

Display payment result

Finally, the miniapp displays the order payment status page to the user.
*Note: Feature must be enabled in Dashboard PartnershipAuthDiagramData formatCurrently, JSON is used for data exchange. Decimal values can be represented as floats, numbers, or strings, with a maximum of 20 digits in total and up to 2 digits after the decimal point. String size limits are defined within the data type specifications.
This endpoint allows the Boxo Platform to create an order payment (refer to Step 3 in the diagram).URL and METHOD:This endpoint must handle a HTTPS POST request URL to endpoint must be provided in DashboardAuthDiagramHeaders:
KeyValue
Authorization<prefix> <base64 encoded(hostapp_client_id:hostapp_secret_key)> or token from Get access token can be used instead
Content-typeapplication/json
X-User-ID<Hostapp user reference>
  • Default <prefix>: Token. Access token prefix can be set in Boxo Connect.
  • To use user access token from Boxo Connect as authorization token enable Use access token in Dashboard.
  • hostapp_client_id and hostapp_secret_key must be provided in Dashboard
Body
FieldData typeDescription
app_idStringMiniapp identifier
orderOrderDetailsOrder info (amount, currency and etc.)
OrderDetails:
FieldData typeOptionalDescription
currencyString(20)NoCurrency code for the order (e.g., ‘USD’)
amountDecimalNoTotal order amount (decimal with 2 decimal places)
subtotal_amountDecimalYesSubtotal before taxes and shipping (decimal with 2 decimal places)
shipping_amountDecimalYesShipping cost (decimal with 2 decimal places)
discount_amountDecimalYesTotal discount applied (decimal with 2 decimal places)
tax_titleString(250)YesTitle/name of the tax
tax_amountDecimalYesTax amount (decimal with 2 decimal places)
taxes_includedBooleanYesBoolean indicating if taxes are included in the price
noteTextYesAdditional notes for the order
custom_attributesJSONYesJSON field for custom order attributes
miniapp_order_idString(255)YesOrder ID from the miniapp side
hostapp_user_idString(255)YesUser ID from the host app
itemsOrderItem[]YesList of order items (see OrderItem below)
shipping_addressObjectYesShipping address details (see OrderShippingAddress below)
OrderItem:
FieldData typeOptionalDescription
product_nameString(250)NoName of the product
product_variant_nameString(250)NoProduct variant name
product_skuString(250)NoProduct SKU/identifier
product_image_urlString(500)NoURL to product image
quantityIntegerNoQuantity of the product (positive integer)
priceDecimalNoPrice per item (decimal with 2 decimal places)
discountDecimalNoDiscount per item (decimal with 2 decimal places)
OrderShippingAddress:
FieldData typeOptionalDescription
address1String(1000)YesPrimary address line
address2String(1000)YesSecondary address line
first_nameString(250)YesFirst name
last_nameString(250)YesLast name
phoneString(250)YesPhone number
region_nameString(100)YesRegion/state name
region_codeString(100)YesRegion/state code
province_nameString(250)YesProvince name
province_codeString(250)YesProvince code
cityString(250)YesCity name
countryString(250)YesCountry name
postal_codeString(250)YesPostal/ZIP code
latitudeDecimalYesGeographic latitude (-90 to 90, 15 decimal places)
longitudeDecimalYesGeographic longitude (-180 to 180, 15 decimal places)
Response:
  • Response status must be 200 in all cases
  • Response body:
FieldData typeOptionalDescription
order_payment_idString(250)No, except error_code providedOrder payment identifier
error_codeStringYesIf some error is occured error code should be provided. Example: {"error_code": "INVALID_ORDER_DATA"} All error codes can be found here
custom_attributesJSONYesJSON field for custom order attributes
Request Example:
    curl --location --request POST '[YOUR_SERVER_URL]/api/create-order-payment/'\
    --header 'Content-Type: application/json' \
    --header 'Authorization: Basic {{BASE64_ENCODED_CLIENT_ID_AND_CLIENT_SECRET}}' \
    --data-raw '{ "app_id": "{{MINIAPP_ID}}", "order": {
        "amount": "100.00",
        "currency": "USD",
        "miniapp_order_id": "{{ MINIAPP_ORDER_ID }}",
        "hostapp_user_id": "{{ HOSTAPP_USER_ID }}"
    }}'
This endpoint is for Boxo platform to get order payment statusURL and METHODThis endpoint must handle a HTTPS POST request Can be configured to be a GET method URL to endpoint must be provided in DashboardAuthDiagramHeaders
KeyValue
Authorization<prefix> <base64 encoded(hostapp_client_id:hostapp_secret_key)> or token from Get access token can be used instead
Content-typeapplication/json
X-User-ID<Hostapp user reference>
Default <prefix>: Token. Access token prefix can be set in Boxo Connect. To use user access token from Boxo Connect as authorization token enable Use access token in Dashboard. hostapp_client_id and hostapp_secret_key must be provided in DashboardBody
FieldData typeDescription
app_idStringMiniapp identifier
client_idStringHostapp identifier
order_payment_idStringOrder payment identifier
Response
  • Response status must be 200 in all cases
  • Response body
FieldData typeOptionalDescription
app_idStringNo, except error_code providedMiniapp identifier
client_idStringNo, except error_code providedHostapp identifier
order_payment_idStringNo, except error_code providedOrder payment identifier
payment_statusString(100)No, except error_code providedOrder payment status: in_process, paid, cancelled, failed
payment_fail_reasonStringYesOrder payment fail reason
custom_attributesJSONYesJSON field for custom order attributes
error_codeStringYesIf some error is occured error code should be provided. Example: {"error_code": "ORDER_NOT_FOUND"} All error codes can be found here
Request Example
    curl --location --request POST '[YOUR_SERVER_URL]/api/get-order-payment-status/'\
    --header 'Content-Type: application/json' \
    --header 'Authorization: Basic {{BASE64_ENCODED_CLIENT_ID_AND_CLIENT_SECRET}}' \
    --data-raw '{ "app_id": "{{MINIAPP_ID}}", "client_id": "{{CLIENT_ID}}", "order_payment_id": "{{ORDER_PAYMENT_ID}}"}'
This endpoint is part of the Boxo Platform. It sends a request to the miniapp server to complete the order payment after the payment has been processed (refer to the step after 10 in the diagram).URL and METHODThis is HTTPS POST /api/v1/orders/complete-order/ endpoint IP address of requesting services must be provided in Dashboard for whitelisting or Request Signaturing must be enabledHeaders
KeyValue
Content-typeapplication/json
Body
FieldData typeOptionalDescription
order_payment_idString(250)NoOrder payment identifier
app_idStringNoMiniapp identifier
client_idStringNoHostapp identifier
payment_statusString(100)NoOrder payment status: in_process, paid, cancelled, failed
payment_fail_reasonStringYesOrder payment fail reason
custom_attributesJSONYesOrder custom attributes
Response:
  • Response status will be 400 in case there is error_code
  • Response body:
FieldData typeDescription
codeStringRequest result code example: SUCCESS
messageStringResult message
error_codeStringError code
error_messageStringResult error message. All error codes can be found here
Request Example
    curl --location --request POST '[BOXO_PLATFORM_SERVER_URL]/api/v1/orders/complete-order/' \
    --header 'Content-Type: application/json' \
    --data-raw '{
        "order_payment_id": "{{ORDER_PAYMENT_ID}}",
        "payment_status": "paid",
        "client_id": "{{CLIENT_ID}}",
        "app_id": "{{MINIAPP_ID}}"
    }'
Response Example
    {
        "code": "SUCCESS",
        "message": "Success"
    }
    {
        "error_code": "ORDER_NOT_FOUND",
        "error_message": "No Order matches the given query."
    }
Listening for Payment event
  • iOS
  • Android
  • Flutter
  • React Native
  • Expo
miniapp.delegate = self
...
extension ViewController : MiniappDelegate {
    func didReceivePaymentEvent(miniapp: Miniapp, paymentData: PaymentData) {
        // Show payment processing screen and handle payment according to paymentData 
        // paymentData.amount
        // paymentData.miniappOrderId 
        // paymentData.currency
        // Once payment is done, modify payment data and send result to mini app: 
        paymentData.status = "success" // change the payment status. "failed" in case payment failed, "cancelled" in case payment cancelled
        miniapp.sendPaymentEvent(paymentData: paymentData)
    }
}
I