NAV
curl

Afterpay In-Store US API v1

Document Version 3.8 | Last updated: Monday, 3 December, 2018

API Production Endpoint

https://posapi.us.afterpay.com/v1/

API Test Endpoint

https://posapi.us-sandbox.afterpay.com/v1/

This document details the Afterpay In-Store API.

REST

The Afterpay In-Store API is organized around REST. The API attempts to use predictable, resource-oriented URLs and to use HTTP response codes to indicate errors.

HTTPS

The Afterpay In-Store API requires all communications to be secured using TLS 1.2 or greater.

Request Headers

Clients must use request headers accordingly:

Dates

All representations of dates are strings in ISO 8601 format.

You can provide date strings that are either UTC (for example, 2015-01-01T00:00:00Z) or offset from UTC to indicate time zone (for example, 2015-01-01T00:00:00-08:00 for eight hours behind UTC).

POS Authentication

To authorize, use this code:

# With shell, you can just pass the correct header with each request. An example request:
curl "https://posapi.us-sandbox.afterpay.com/v1/" \
  -H 'Authorization: Bearer  <deviceAccessToken>' 

Make sure to replace deviceAccessToken a valid access token.

The Afterpay In-Store API uses access tokens to allow access to the API. Access tokens are created using the Create Token endpoint.

The Afterpay In-Store API expects the access token to be included in all API requests as a HTTP header that looks like the following:

Authorization: Bearer <deviceAccessToken>

POS Operator Identification

# With shell, you can just pass the correct header with each request
curl "https://posapi.us-sandbox.afterpay.com/v1/" \
  -H "Operator: operator-id"

Make sure to replace operator-id with the operator’s ID.

With the exception of the device activation and create token endpoints, Afterpay expects for the Operator ID to be included in all posapi.us.afterpay.com API requests to the server in a header that looks like the following:

Operator: operator-id

Idempotent Requests

The Afterpay In-Store API supports idempotency that allows the safe retry of requests guaranteeing the operation is only performed once.

If for example an order request fails with a network error, the request can be retried with the same requestId.

We recommend that you use UUIDs as request IDs. The resources that include a requestId will send back the same response for requests made with the same requestId for up to 24 hours.

Distributed State Considerations

It is important that integrators consider all failure scenarios associated with sending an order/refund request over the network, which is inherently unreliable.

Afterpay recommends the following implementation steps to guard against state inconsistencies between the POS and Afterpay:

Timeouts

Afterpay will attempt to respond to requests as soon as possible, but often latency delays are outside of our control. Where an API call is dependant on downstream banking networks the response times can be higher. As a guideline this document provides recommended network connection open timeout and read timeout values for each API resource. Resources that are dependant on banking networks will have higher timeout values. All resources that are identified as idempotent can be safely retried before the recommended timeout periods.

Models

Money object

Example money object

{
    "amount": "29.99",
    "currency": "USD"
}

Attributes

Parameter Type Description
amount string The amount should be a string representation of a decimal number. Unless otherwise indicated the precision should be the standard precision for the currency of the amount.
currency string The currency is a ISO 4217 format value. Currently only USD is supported.

Item object

Represents an item in the order. All fields are required.

Example item object

 {
    "name": "widget",
    "sku": "123412234",
    "quantity": 1,
    "price": {
        "amount": "10.00",
        "currency": "USD"
    }
}

Attributes

Parameter Type Description
name string A name of the item.
sku string The SKU of the item.
quantity number The number of items purchased.
price Money The unit price of the individual item. Must be a positive value.

Service Status

Ping

This endpoint can be used to check that the service is reachable and available.

Example Ping Request

curl "https://posapi.us-sandbox.afterpay.com/ping" 

Response (200)

HTTP Request

GET /ping

Device Authentication

Device Activation

Example Device Activation Request

curl "https://posapi.us-sandbox.afterpay.com/v1/devices/activate" \
  -X POST \
  -H 'Content-Type: application/json' \
  -H 'User-Agent: Merchant XYZ; POS Platform/1.0.0; Merchant/60032000' \
  -H 'Accept: application/json' \
  -d '{
       "secret":"111333331001",
       "name": "POS1234",
       "attributes": {
         "terminal": "NCR",
         "hardwareId": "678678"
       }
  }'

Response (201)

{
    "deviceId":1234,
    "key":"apikey_bb68452ad2d743db75a270bf2c305df9abeefc"
}

This endpoint performs a one time activation of a device, providing a device’s identification and authorization credentials. The device credentials obtained from the activation request should be securely stored on the device. The device credentials are required to create access tokens used for authentication.

HTTP Request

POST /v1/devices/activate

HTTP Headers

Parameter Description
Content-Type application/json
User-Agent {merchantName}; {platform}/{platformVersion}; Merchant/{merchantId}
Accept application/json

Arguments

Parameter Type Description
secret required string The terminal secret provided for activation.
name required string An identifier for the terminal being activated.
attributes optional A map that can be populated with device specific information.

Response

Returns the device’s authorization credentials

Parameter Description
deviceId A device ID required for auditing and authentication.
key A secret key required for authentication.

Errors

Can return the following specific error responses

Status Code Type Description
401 unauthorized Will be returned if the secret is invalid for the device name.

Connection timeouts

Timeout Time (seconds)
Open 10
Read 20

Create Token

Example Create Token Request

curl "https://posapi.us-sandbox.afterpay.com/v1/devices/123/token" \
  -X POST \
  -H 'Content-Type: application/json' \
  -H 'User-Agent: Merchant XYZ; POS Platform/1.0.0; Merchant/60032000' \
  -H 'Accept: application/json' \
  -d '{
        "key":"bb68452ad2d743db75a270bf2c305df9abeefcb3e02084fc1ff7a3ba61ed46d5"
      }'

Response (201)

{
     "token":"86bc8b2b973d5046d82432862254dfb5967a6db7c844bf615ab8eba17082105b",
     "expiresIn":85800
}

This endpoint creates a device access token. The device will need to periodically renew the access token, indicated by expiresIn, required by all API endpoints.

HTTP Request

POST /v1/devices/{deviceId}/token

URL Parameters

Parameter Description
deviceId The device ID obtained during activation

HTTP Headers

Parameter Description
Content-Type application/json
User-Agent {merchantName}; {platform}/{platformVersion}; Merchant/{merchantId}
Accept application/json

Arguments

Parameter Description
key The device secret key obtained during activation

Response

Returns the devices access token

Parameter Description
token An access token.
expiresIn The access token’s expiry time in seconds.

Errors

Can return the following specific error responses

Status Code Type Description
401 unauthorized Will be returned if the secret is invalid.

Connection timeouts

Timeout Time (seconds)
Open 10
Read 20

Order (Payment)

Create Order

Example Order Request

curl "https://posapi.us-sandbox.afterpay.com/v1/orders" \
  -X POST \
  -H 'Authorization: Bearer 86bc8b2b973d5046d82432862254dfb5967a6db7c844bf615ab8eba17082105b' \
  -H 'Content-Type: application/json' \
  -H 'Operator: Dante Hicks' \
  -H 'User-Agent: Merchant XYZ; POS Platform/1.0.0; Merchant/60032000; Device/100' \
  -H 'Accept: application/json' \
  -d '{
    "requestId":"61cdad2d-8e10-42ec-a97b-8712dd7a8ca9",
    "requestedAt":"2015-07-14T10:08:14.123Z",
    "preApprovalCode":"12FA1G3C2E9D",
    "amount": {
        "amount": "15.00",
        "currency": "USD"
    },
    "merchantReference": "123987",
    "orderItems": [
        {
            "name": "widget",
            "sku": "123412234",
            "quantity": 1,
            "price": {
                "amount": "10.00",
                "currency": "USD"
            }
        },
        {
            "name": "blob",
            "sku": "123324u4",
            "quantity": 1,
            "price": {
                "amount": "5.00",
                "currency": "USD"
            }
        }
     ]
  }'

Response (201)

{
    "orderId":"100012",
    "orderedAt":"2015-07-14T10:08:15.456Z",
    "requestId":"61cdad2d-8e10-42ec-a97b-8712dd7a8ca9",
    "requestedAt":"2015-07-14T10:08:14.123Z",
    "preApprovalCode":"12FA1G3C2E9D",
    "amount": {
        "amount": "15.00",
        "currency": "USD"
    },
    "merchantReference": "123987",
    "orderItems": [
        {
            "name": "widget",
            "sku": "123412234",
            "quantity": 1,
            "price": {
                "amount": "10.00",
                "currency": "USD"
            }
        },
        {
            "name": "blob",
            "sku": "123324u4",
            "quantity": 1,
            "price": {
                "amount": "5.00",
                "currency": "USD"
            }
        }
     ]
}

This resource creates an order.

HTTP Request

POST /v1/orders

HTTP Headers

Parameter Description
Authorization The Bearer token returned from /v1/devices/token.
Content-Type application/json
Operator The POS/Terminal Operator ID.
User-Agent {merchantName}; {platform}/{platformVersion}; Merchant/{merchantId}; Device/{deviceId}
Accept application/json

Arguments

Parameter Type Description
requestId string A client created unique request ID. It is recommended that the client generate a GUID as no mechanism is provided to synchronise a incrementing id should the sequence repeat.
requestedAt string (ISO-8601) A timestamp of the client order payment request time (ISO 8601 UTC/Zulu time).
merchantReference string A reference id linking this order payment to an object in the merchant’s system. For example the POS basket ID.
preApprovalCode string The pre-approval alphanumeric code obtained from the barcode displayed on the customers mobile.
amount Money The payment amount.
orderItems Item[] required A list of order items.

Response

Returns the order response. In addition to returning all fields present in the request, the response will also include the following two new fields.

Parameter type Description
orderId string The order ID is a unique numerical ID suitable for inclusion on a customer invoice.
orderedAt string (ISO-8601) A timestamp of the completed transaction (ISO 8601 UTC/Zulu time).

Errors

Can return the following specific error responses in addition to general errors outlined below.

Status Code Error Code Description
402 declined transaction declined.
402 minimum_not_met order amount is below the minimum pre-approval amount.
402 exceed_preapproval order amount exceeded pre-approval amount.
409 conflict Another request with this request id is currently being processed.
412 invalid_code Will be returned if the code: has expired, has been used, is invalid.

Connection timeouts

Timeout Time (seconds)
Open 10
Read 70

Reverse Order

Example Order Reversal Request

curl "https://posapi.us-sandbox.afterpay.com/v1/orders/reverse" \
  -X POST \
  -H 'Authorization: Bearer 86bc8b2b973d5046d82432862254dfb5967a6db7c844bf615ab8eba17082105b' \
  -H 'Content-Type: application/json' \
  -H 'Operator: Dante Hicks' \
  -H 'User-Agent: Merchant XYZ; POS Platform/1.0.0; Merchant/60032000; Device/100' \
  -H 'Accept: application/json' \
  -d '{
    "requestedAt":"2015-07-14T10:08:14Z",
    "reversingRequestId":"61cdad2d-8e10-42ec-a97b-8712dd7a8ca9"
  }'

Response (202)

{   
    "reverseId":"100020",
    "reversedAt":"2015-07-14T10:08:15.456Z",
    "requestedAt":"2015-07-14T10:08:14Z",
    "reversingRequestId":"61cdad2d-8e10-42ec-a97b-8712dd7a8ca9"
}

This resource reverses a previous order.

Reversals are system level requests that ensure network failures don’t result in inconsistent state between the client and server. The client should send a reversal if it doesn’t received a response within 30 seconds. Reversals are idempotent.

HTTP Request

POST /v1/orders/reverse

HTTP Headers

Parameter Description
Authorization The Bearer token returned from /v1/devices/token.
Content-Type application/json
Operator The POS/Terminal Operator ID.
User-Agent {merchantName}; {platform}/{platformVersion}; Merchant/{merchantId}; Device/{deviceId}
Accept application/json

Arguments

Parameter Type Description
requestedAt required string (ISO 8601) A timestamp of the client order request time (ISO 8601 UTC/Zulu time).
reversingRequestId required string The request ID for the previous submitted order request.

Response

Returns the reversal response

Parameter Type Description
reverseId string The reversal ID.
reversedAt string (ISO-8601) A timestamp of the completed reversal transaction.

Errors

Can return the following specific error responses

Status Code Error Code Description
412 precondition_failed The reversingRequestId was not found. This might occur if the initial request was never received by the server or the reversal request occurs after 24 hours of the original request.

Connection timeouts

Timeout Time (seconds)
Open 10
Read 20

Refund

Create Refund

Example Refund Request

curl "https://posapi.us-sandbox.afterpay.com/v1/refunds" \
  -X POST \
  -H 'Authorization: Bearer 86bc8b2b973d5046d82432862254dfb5967a6db7c844bf615ab8eba17082105b' \
  -H 'Content-Type: application/json' \
  -H 'Operator: Dante Hicks' \
  -H 'User-Agent: Merchant XYZ; POS Platform/1.0.0; Merchant/60032000; Device/100' \
  -H 'Accept: application/json' \
  -d '{
    "requestId": "7c4bdcd7-09b2-4a2d-a7cb-5017b621d6f7",
    "requestedAt": "2015-07-14T10:08:14.123Z",
    "merchantReference": "123987",
    "orderId": "100015",
    "orderMerchantReference": "100012",
    "amount": {
        "amount": "10.00",
        "currency": "USD"
    }
  }'

Response (201)

{
    "refundId": "100016",
    "refundedAt": "2015-07-14T10:08:15.456Z",
    "requestId": "7c4bdcd7-09b2-4a2d-a7cb-5017b621d6f7",
    "requestedAt": "2015-07-14T10:08:14.123Z",
    "merchantReference": "123987",
    "orderId": "100015",
    "orderMerchantReference": "100012",
    "amount": {
        "amount": "10.00",
        "currency": "USD"
    }
}

This resource performs a full or partial refund.

HTTP Request

POST /v1/refunds

HTTP Headers

Parameter Description
Authorization The Bearer token returned from /v1/devices/token.
Content-Type application/json
Operator The POS/Terminal Operator ID.
User-Agent {merchantName}; {platform}/{platformVersion}; Merchant/{merchantId}; Device/{deviceId}
Accept application/json

Arguments

Parameter Type Description
requestId required string A client created unique request ID. It is recommended that the client generate a GUID as no mechanism is provided to synchronise a incrementing id should the sequence repeat.
requestedAt required string (ISO-8601) A timestamp of the client refund request time (ISO 8601 UTC/Zulu time).
merchantReference optional string A reference id linking this refund to an object in the merchant’s system. For example the POS refund ID.
orderId required string The original order ID to apply the refund to
orderMerchantReference optional string The original Order’s merchantReference. If the supplied value does not match the original Order a error will be returned.
amount required Money The refund amount. The refund amount can not exceed the associated order.

Response

Returns the refund response. In addition to the fields in the original request, the response includes the following:

Parameter Type Description
refundId string The refund ID is a unique numerical ID suitable for inclusion on a customer invoice.
refundedAt string (ISO-8601) A timestamp of the completed refund transaction.

Errors

Can return the following specific error responses

Status Code Error code Description
409 conflict Another request with this request id is currently being processed.
412 invalid_order_merchant_reference The supplied orderMerchantReference did not match the original Order.
412 precondition_failed The orderId was not found or was not eligible for a refund.
422 invalid_amount The sum of all refunds for the given order, including the new refund, exceed the initial order amount.

Connection timeouts

Timeout Time (seconds)
Open 10
Read 20

Refund Reversal

Example Reverse Refund Request

curl "https://posapi.us-sandbox.afterpay.com/v1/refunds/reverse" \
  -X POST \
  -H 'Authorization: Bearer 86bc8b2b973d5046d82432862254dfb5967a6db7c844bf615ab8eba17082105b' \
  -H 'Content-Type: application/json' \
  -H 'Operator: Dante Hicks' \
  -H 'User-Agent: Merchant XYZ; POS Platform/1.0.0; Merchant/60032000; Device/100' \
  -H 'Accept: application/json' \
  -d '{
    "requestedAt":"2015-07-14T10:08:14.123Z",
    "reversingRequestId":"7c4bdcd7-09b2-4a2d-a7cb-5017b621d6f7"
  }'

Response (202)

{
    "reverseId":"100018",
    "reversedAt":"2015-07-14T10:08:15.456Z",
    "requestedAt":"2015-07-14T10:08:14.123Z",
    "reversingRequestId":"7c4bdcd7-09b2-4a2d-a7cb-5017b621d6f7"
}

This resource reverses a previous refund.

Reversals are system level requests that ensure network failures don’t result in inconsistent state between the client and server. The client should send a reversal if it doesn’t received a response within 40 second. Reversals are idempotent.

HTTP Request

POST /v1/refunds/reverse

HTTP Headers

Parameter Description
Authorization The Bearer token returned from /v1/devices/token.
Content-Type application/json
Operator The POS/Terminal Operator ID.
User-Agent {merchantName}; {platform}/{platformVersion}; Merchant/{merchantId}; Device/{deviceId}
Accept application/json

Arguments

Parameter Type Description
requestedAt required string (ISO-8601) A timestamp of the client refund request time (ISO 8601 UTC/Zulu time).
reversingRequestId required string The request ID for the previous submitted refund request.

Response

Returns the reversal response

Parameter Type Description
reverseId string The reversal ID.
reversedAt string (ISO-8601) A timestamp of the completed reversal transaction.

Errors

Can return the following specific error responses

Status Code Error Code Description
412 precondition_failed The reversingRequestId was not found. This might occur if the initial request was never received by the server or the reversal request occurs after 24 hours of the original request.

Connection timeouts

Timeout Time (seconds)
Open 10
Read 20

Errors

Example Invalid Create Purchase Request

curl "https://example.afterpay.com/v1/example" \
  -X POST \
  -d '{
          "amount": {
              "amount": "-250.15",
              "currency": "USD"
          }
      },'

If the given parameters are incorrect, you will receive a HTTP 400 response

HTTP/1.1 400 Bad Request
Cache-Control: must-revalidate,no-cache,no-store
Content-length: 1327
Content-Type: text/html;charset=ISO-8859-1
Date: Thu, 24 Apr 2014 15:15:11 GMT
Connection: keep-alive

The above command returns JSON structured like so:

{
  "errorCode" : "invalid_object",
  "errorId" : "cf5907fbf8fbc417",
  "message" : "[totalAmount must be greater than 0.00 (was USD -250.15)]",
  "httpStatusCode" : 422
}

The Afterpay API uses conventional HTTP response codes to indicate success or failure of an API request.

In general, codes in the 2xx range indicate success, codes in the 4xx range indicate an error that resulted from the provided information (e.g. a required parameter was missing), and codes in the 5xx range indicate an error with the Afterpay servers.

Response

Returns a JSON response and appropriate HTTP status code

Attributes description
httpStatusCode The HTTP status code
errorId A unique error ID.
errorCode The type of error returned. For example, invalid_object, transaction_error, or server_error.
message A human-readable message giving more details about the error. For card errors, these messages can be shown to your users.

Some examples of status codes that might be returned by the Afterpay API are below. This list is not exhaustive, and other status codes may be encountered specific to the resource.

HTTP Status Code HTTP Status Name Meaning
400 Bad Request Your request is a little wrong.
401 Unauthorized Your API key is wrong or access token is invalid.
402 Payment Required Generally returned in cases where payments are declined.
404 Not Found The specified resource could not be found.
405 Method Not Allowed You tried to access a resource with an invalid method.
406 Not Acceptable You requested a format that isn’t json.
409 Conflict You tried to perform an operation that conflicts with another operation.
410 Gone The resource requested has been removed from our servers.
412 Precondition Failed A prerequisite step that was required before calling the resource had not been performed.
422 Unprocessable Entity The request format was valid, however one or more values were incorrect.
429 Too Many Requests Too many requests may occur if an abnormal number of requests occur.
500 Internal Server Error We had a problem with our server. Try again later.
503 Service Unavailable We’re temporarially offline for maintanance. Please try again later.