APG PayAPG Paydocs

Payments

Create and pay an order

Separate what is owed from the act of paying it, and see why that separation is useful.

An order is what is owed. A transaction is money moving. Keeping them apart is what lets one order be paid by two cards, or retried after a decline without re-stating the amount, or left unpaid without anything having failed.

This is why POST /transactions takes an orderId and no amount: the order already carries it.

The amount is in minor units with the currency stated once beside it, 9500 with AUD is $95.00.

Request
curl -X POST "https://api.tst.au.apgpay.dev/bezel/orders" \
  -H "Authorization: Bearer $API_SECRET_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "order": {
    "merchantId": "<useMerchantIdFromSeed>",
    "customerId": "<useCustomerIdFromSeed>",
    "orderType": "Online",
    "referenceOrderId": "web-order-10423",
    "description": "2kg Ethiopian single origin",
    "amount": 9500,
    "currency": "AUD",
    "billing": {
      "name": "Priya Raman",
      "address": {
        "line1": "12 Smith Street",
        "line2": null,
        "city": "Sydney",
        "state": "NSW",
        "postalCode": "2000",
        "country": "AU",
        "type": "OrdrAddressAttributes"
      },
      "phone": "+61412345678",
      "type": "OrdrBillingAttributes"
    },
    "emailAddress": "priya.raman@example.com",
    "phoneNumber": "+61412345678",
    "lineItems": [],
    "taxIncluded": true,
    "taxAmount": 864,
    "discount": null,
    "shipping": null,
    "request3DSOnPayment": null,
    "emailCustomerReceipt": true,
    "settlement": null,
    "metadata": null,
    "type": "OrdrNewOrderAttributes"
  },
  "type": "OrdrCmdCreate"
}'

The only operation that touches a card number, which is why it is the only one with PCI obligations.

Request
curl -X POST "$VAULT_BASE_URL/payment-tokens" \
  -H "Authorization: Bearer $API_PUBLISHABLE_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "amount": {
    "minorCurrencyUnits": 9500,
    "currency": "AUD"
  },
  "cardNumber": "4111111111111111",
  "cvc": "123",
  "expiryMonth": 12,
  "expiryYear": 2030,
  "cardHolderName": "Priya Raman",
  "threeDsSessionId": null,
  "surcharge": null,
  "type": "PtknCmdCreateFromCard"
}'

Name the order and the token. No amount, see above.

Request
curl -X POST "https://api.tst.au.apgpay.dev/bezel/transactions" \
  -H "Authorization: Bearer $API_SECRET_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "orderId": "<useOrderIdFromStep1>",
  "paymentTokenId": "<usePaymentTokenIdFromStep2>",
  "authoriseOnly": null,
  "requestThreeDS": null,
  "returnUrl": "https://bluehillcoffee.example/checkout/complete",
  "offSession": null,
  "cardStatementName": null,
  "cardStatementCity": null,
  "referenceTransactionId": "web-order-10423",
  "type": "TranCmdCreate"
}'

The order knows what has been paid against it, so this is how you tell a part-paid order from an unpaid one.

Request
curl -X GET "https://api.tst.au.apgpay.dev/bezel/orders/<useOrderIdFromStep1>" \
  -H "Authorization: Bearer $API_SECRET_KEY"

See authorise then capture.