Skip to main content

Qashier Online Payment API (1.0.0)

Checkout Session

A Checkout Session represents your customer's session as they pay for one-time purchases through Checkout. We recommend creating a new Session each time your customer attempts to pay.

You can create a Checkout Session on your server and redirect to its URL to begin Checkout.

Related guide: Accept a payment

Authentication

Qashier uses API keys to authenticate requests. You can view and manage your API keys in your Qashier Dashboard.

Your API keys carry many privileges, so be sure to keep them secure! Do not share your secret API keys in publicly accessible areas such as GitHub, client-side code, and so forth.

Authentication to the API is performed via HTTP Basic Auth. Provide your API key as the basic auth username value and leave the password empty:

curl https://api.qashier.com/v3/payment/qpay/checkout/sessions \
  -u sk_test_4eC39HqLyjWDarjtT1zdp7dc:

Alternatively, you can manually construct the Authorization header:

Authorization: Basic <base64(sk_test_4eC39HqLyjWDarjtT1zdp7dc:)>

All API requests must be made over HTTPS. Calls made over plain HTTP will fail. API requests without authentication will also fail.

Idempotency Keys

The API supports idempotency keys to prevent duplicate requests. When you include an Idempotency-Key header with your POST request, the server will ensure that:

  • If a request with the same idempotency key has already been processed, the API returns the same response without processing the request again
  • The idempotency key should be unique for each distinct request
  • Keys are automatically removed from the system after 24 hours
  • Maximum key length is 255 characters

Example with Idempotency Key

curl -X POST https://api.qashier.com/v3/payment/qpay/checkout/sessions \
  -u sk_test_4eC39HqLyjWDarjtT1zdp7dc: \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: 550e8400-e29b-41d4-a716-446655440000" \
  -d '{
    "return_url": "https://your-site.com/return",
    "success_url": "https://your-site.com/success",
    "line_items": [...]
  }'

Request IDs

Each API request has an associated request identifier that is automatically generated by the server. You can find this value in the response headers, under Request-Id.

If you need to contact us about a specific request, providing the request identifier will ensure the fastest possible resolution.

Request IDs follow the format req_ followed by alphanumeric characters and underscores.

Example Request

curl -X POST https://api.qashier.com/v3/payment/qpay/checkout/sessions \
  -u sk_test_4eC39HqLyjWDarjtT1zdp7dc: \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: 550e8400-e29b-41d4-a716-446655440000" \
  -d '{
    "return_url": "https://your-site.com/return",
    "success_url": "https://your-site.com/success",
    "line_items": [...]
  }'

Response Headers

All API responses include a Request-Id header that you can use for debugging:

Request-Id: req_abc123def456ghi789

Errors

Qashier uses conventional HTTP response codes to indicate the 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 failed given the information provided (e.g., a required parameter was omitted, authentication failed, etc.)
  • Codes in the 5xx range indicate an error with Qashier's servers

Some 4xx errors that could be handled programmatically include an error code that briefly explains the error reported.

HTTP Status Code Summary

  • 200 - OK: Everything worked as expected
  • 400 - Bad Request: The request was unacceptable, often due to missing a required parameter
  • 401 - Unauthorized: No valid API key provided
  • 403 - Forbidden: The API key doesn't have permissions to perform the request
  • 404 - Not Found: The requested resource doesn't exist
  • 409 - Conflict: The request conflicts with another request (perhaps due to using the same idempotency key)
  • 500 - Server Errors: Something went wrong on Qashier's end

Error Types

  • api_error: API errors cover any other type of problem (e.g., a temporary problem with Qashier's servers) and are extremely uncommon
  • authentication_error: Failure to properly authenticate yourself in the request
  • idempotency_error: Idempotency errors occur when an Idempotency-Key is re-used on a request that does not match the first request's API endpoint and parameters
  • invalid_request_error: Invalid request errors arise when your request has invalid parameters

Error Object

{
  "error": {
    "type": "invalid_request_error",
    "code": "parameter_missing",
    "message": "Missing required parameter: return_url",
    "param": "return_url"
  }
}

Error Attributes

  • type (string): The type of error returned. One of api_error, authentication_error, idempotency_error, invalid_request_error, or rate_limit_error
  • code (string): For some errors that could be handled programmatically, a short string indicating the error code reported
  • message (string): A human-readable message providing more details about the error
  • param (string): If the error is parameter-specific, the parameter related to the error. For example, you can use this to display a message near the correct form field

Endpoints

API endpoints for managing payment online checkout sessions

Create a Checkout Session

Creates a Checkout Session object.

Authorizations:
basicAuth
header Parameters
Idempotency-Key
string <= 255 characters
Example: 550e8400-e29b-41d4-a716-446655440000

A unique value generated by the client which the server uses to recognize subsequent retries of the same request. The key can be any unique string up to a maximum of 255 characters.

Request Body schema: application/json
required
expires_at
integer

The Epoch time in seconds at which the Checkout Session will expire. It can be anywhere from 30 minutes to 24 hours after Checkout Session creation. By default, this value is 24 hours from creation

required
Array of objects (LineItem)

The items the customer is purchasing.

Array
unit_amount
required
integer

A non-negative integer in cents representing how much to charge

quantity
required
integer

The quantity of the item being purchased. Limit to 1.

currency
required
string

Three-letter ISO 4217 currency code in uppercase (e.g., 'SGD', 'MYR', 'PHP')

return_url
required
string

The URL to redirect your customer back to after they authenticate or cancel their payment on the payment method's app or site.

success_url
required
string

The URL to which Qashier should send customers when payment or setup is complete

Responses

Callbacks

Request samples

Content type
application/json
{
  • "expires_at": 0,
  • "line_items": [
    ],
  • "currency": "SGD",
  • "return_url": "string",
  • "success_url": "string"
}

Response samples

Content type
application/json
{
  • "object": "checkout.session",
  • "id": "string",
  • "currency": "string",
  • "amount_total": 0,
  • "created_at": 0,
  • "expires_at": 0,
  • "payment_status": "paid",
  • "payment_method": "string",
  • "status": "open",
  • "return_url": "string",
  • "success_url": "string",
  • "url": "string",
  • "refunded": true
}

Callback payload samples

Callback
POST: Checkout Session Webhook
Content type
application/json
{
  • "id": "evt_1234567890",
  • "api_version": "string",
  • "request": {
    },
  • "type": "checkout.session.completed",
  • "account": "string",
  • "created": 0,
  • "data": {
    }
}

List all Checkout Sessions

Returns a list of Checkout Sessions.

A dictionary with a data property that contains an array of up to limit Checkout Sessions, starting after Checkout Session starting_after. Each entry in the array is a separate Checkout Session object. If no more Checkout Sessions are available, the resulting array will be empty.

Authorizations:
basicAuth
query Parameters
object

Only return Checkout Sessions created during the given date interval

ending_before
string

A cursor for use in pagination. ending_before is an object ID that defines your place in the list. For instance, if you make a list request and receive 100 objects, starting with obj_bar, your subsequent call can include ending_before=obj_bar in order to fetch the previous page of the list.

limit
integer [ 1 .. 100 ]
Default: 10

A limit on the number of objects to be returned. Limit can range between 1 and 100, and the default is 10.

starting_after
string

A cursor for use in pagination. starting_after is an object ID that defines your place in the list. For instance, if you make a list request and receive 100 objects, ending with obj_foo, your subsequent call can include starting_after=obj_foo in order to fetch the next page of the list.

status
string
Enum: "open" "complete" "expired"

Only return the Checkout Sessions matching the given status.

Possible values:

  • complete: The checkout session is complete. Payment processing may still be in progress
  • expired: The checkout session has expired. No further processing will occur
  • open: The checkout session is still in progress. Payment processing has not started

Responses

Response samples

Content type
application/json
{
  • "object": "list",
  • "data": [
    ],
  • "has_more": true,
  • "url": "/checkout/sessions"
}

Retrieve a Checkout Session

Retrieves a Checkout Session object.

Authorizations:
basicAuth
path Parameters
id
required
string

The ID of the Checkout Session to retrieve

Responses

Response samples

Content type
application/json
{
  • "object": "checkout.session",
  • "id": "string",
  • "currency": "string",
  • "amount_total": 0,
  • "created_at": 0,
  • "expires_at": 0,
  • "payment_status": "paid",
  • "payment_method": "string",
  • "status": "open",
  • "return_url": "string",
  • "success_url": "string",
  • "url": "string",
  • "refunded": true
}

Expire a Checkout Session

A Checkout Session can be expired when it is in one of these statuses: open

After it expires, a customer can't complete a Checkout Session and customers loading the Checkout Session see a message saying the Checkout Session is expired.

Returns a Checkout Session object if the expiration succeeded. Returns an error if the Checkout Session has already expired or isn't in an expireable state.

Authorizations:
basicAuth
path Parameters
id
required
string

The ID of the Checkout Session to expire

header Parameters
Idempotency-Key
string <= 255 characters
Example: 550e8400-e29b-41d4-a716-446655440000

A unique value generated by the client which the server uses to recognize subsequent retries of the same request. The key can be any unique string up to a maximum of 255 characters.

Responses

Response samples

Content type
application/json
{
  • "object": "checkout.session",
  • "id": "string",
  • "currency": "string",
  • "amount_total": 0,
  • "created_at": 0,
  • "expires_at": 0,
  • "payment_status": "paid",
  • "payment_method": "string",
  • "status": "open",
  • "return_url": "string",
  • "success_url": "string",
  • "url": "string",
  • "refunded": true
}

Refunds

Refund payments from completed checkout sessions

Refund a Payment

Refunds a payment from a completed Checkout Session.

When you create a refund, the amount is returned to the original payment method. Refund requests are processed asynchronously, and the refund status will be updated accordingly.

Authorizations:
basicAuth
Request Body schema: application/json
required
sessionId
required
string

The ID of the checkout session to refund

Responses

Request samples

Content type
application/json
{
  • "sessionId": "59a6ceea-3079-4032-8eee-906cc354a588"
}

Response samples

Content type
application/json
{
  • "object": "refund",
  • "session_id": "59a6ceea-3079-4032-8eee-906cc354a588",
  • "created_at": 1729166400,
  • "amount": 1000,
  • "currency": "SGD",
  • "status": "pending"
}

Webhooks

Webhook events sent to your server

Webhook Authentication

Qashier signs webhook events it sends to your endpoints by including a signature in each event's Qashier-Signature header. This allows you to verify that the events were sent by Qashier, not by a third party.

Signature Header Format

The Qashier-Signature header contains a timestamp and one or more signatures. The timestamp is prefixed by t=, and each signature is prefixed by a scheme. Schemes start with v, followed by an integer. Currently, the only valid scheme is v1.

Qashier-Signature: t=1625669316,v1=abc123def456...

Verifying Signatures

Qashier generates signatures using SHA-256. To verify a signature, you'll need to:

  1. Extract the timestamp and signatures from the header
  2. Prepare the signed payload by concatenating:
    • The timestamp (as a string)
    • The character .
    • The raw request body
  3. Compute a SHA256 hash function, using the webhook secret provided as the key and the signed payload as the message
  4. Compare your signature to the signatures in the header using a constant-time comparison

Checkout Session Updated Webhook

Occurs when a Checkout Session has been updated

header Parameters
Qashier-Signature
required
string
Example: t=1625669316,v1=5257a869e7ecebeda32affa62cdca3fa51cad7e77a0e56ff536d0ce8e108d8bd

Contains the webhook signature for verification. Format: t=<timestamp>,v1=<signature>

Example: t=1625669316,v1=abc123def456...

Request Body schema: application/json
required
id
string

Unique identifier for the event

api_version
string

The Qashier API version used to render data when the event was created.

object
id
string

The request ID of the request that triggered this event

idempotency_key
string

The idempotency key used for the request

type
string
Enum: "checkout.session.completed" "checkout.session.expired"
  • checkout.session.completed
  • checkout.session.expired
account
string

The ID of the account that this event belongs to

created
integer

Time at which the object was created (Unix timestamp)

object
object (CheckoutSession)
object
string
Value: "checkout.session"

String representing the object's type. Objects of the same type share the same value.

id
string

Unique identifier for the object

currency
string

Three-letter ISO currency code

amount_total
integer

Total of all items after discounts and taxes are applied

created_at
integer

Time at which the object was created

expires_at
integer

The Epoch time at which the Checkout Session will expire

payment_status
string
Enum: "paid" "unpaid" "no_payment_required"

The payment status of the Checkout Session

payment_method
string

The payment method used for the Checkout Session

status
string
Enum: "open" "complete" "expired"

The status of the Checkout Session

return_url
string

URL to redirect customer to another page for async payments

success_url
string

URL customers will be directed to after successful payment

url
string

The URL to the Checkout Session

refunded
boolean

Whether the Checkout Session has been refunded

Request samples

Content type
application/json
{
  • "id": "sess_123",
  • "api_version": "1.0.0",
  • "request": {
    },
  • "type": "checkout.session.completed",
  • "account": "acct_987654321",
  • "created": 1725348200,
  • "data": {
    }
}

Refund Webhook

Occurs when a Refund has been updated

header Parameters
Qashier-Signature
required
string
Example: t=1625669316,v1=5257a869e7ecebeda32affa62cdca3fa51cad7e77a0e56ff536d0ce8e108d8bd

Contains the webhook signature for verification. Format: t=<timestamp>,v1=<signature>

Example: t=1625669316,v1=abc123def456...

Request Body schema: application/json
required
id
string

Unique identifier for the event

api_version
string

The Qashier API version used to render data when the event was created.

object
id
string

The request ID of the request that triggered this event

idempotency_key
string

The idempotency key used for the request

type
string
account
string

The ID of the account that this event belongs to

created
integer

Time at which the object was created (Unix timestamp)

object
object (Refund)
object
string
Value: "refund"

String representing the object's type. Objects of the same type share the same value.

session_id
string

The ID of the checkout session that was refunded

created_at
integer

Time at which the refund was created (Unix timestamp)

amount
integer

Amount refunded in cents

currency
string

Three-letter ISO currency code in uppercase

status
string (RefundStatus)
Enum: "pending" "succeeded" "failed"

The status of the refund

Request samples

Content type
application/json
{
  • "id": "sess_123",
  • "api_version": "1.0.0",
  • "request": {
    },
  • "type": "refund",
  • "account": "acct_987654321",
  • "created": 1725348200,
  • "data": {
    }
}

CheckoutSession

object
string
Value: "checkout.session"

String representing the object's type. Objects of the same type share the same value.

id
string

Unique identifier for the object

currency
string

Three-letter ISO currency code

amount_total
integer

Total of all items after discounts and taxes are applied

created_at
integer

Time at which the object was created

expires_at
integer

The Epoch time at which the Checkout Session will expire

payment_status
string
Enum: "paid" "unpaid" "no_payment_required"

The payment status of the Checkout Session

payment_method
string

The payment method used for the Checkout Session

status
string
Enum: "open" "complete" "expired"

The status of the Checkout Session

return_url
string

URL to redirect customer to another page for async payments

success_url
string

URL customers will be directed to after successful payment

url
string

The URL to the Checkout Session

refunded
boolean

Whether the Checkout Session has been refunded

{
  • "object": "checkout.session",
  • "id": "string",
  • "currency": "string",
  • "amount_total": 0,
  • "created_at": 0,
  • "expires_at": 0,
  • "payment_status": "paid",
  • "payment_method": "string",
  • "status": "open",
  • "return_url": "string",
  • "success_url": "string",
  • "url": "string",
  • "refunded": true
}

LineItem

unit_amount
required
integer

A non-negative integer in cents representing how much to charge

quantity
required
integer

The quantity of the item being purchased. Limit to 1.

{
  • "unit_amount": 0,
  • "quantity": 0
}

Refund

object
string
Value: "refund"

String representing the object's type. Objects of the same type share the same value.

session_id
string

The ID of the checkout session that was refunded

created_at
integer

Time at which the refund was created (Unix timestamp)

amount
integer

Amount refunded in cents

currency
string

Three-letter ISO currency code in uppercase

status
string (RefundStatus)
Enum: "pending" "succeeded" "failed"

The status of the refund

{
  • "object": "refund",
  • "session_id": "string",
  • "created_at": 0,
  • "amount": 0,
  • "currency": "string",
  • "status": "pending"
}