GraphQL API Overview
AccruPay exposes a single GraphQL endpoint. All merchant operations — transactions, sessions, payment methods, payment plans — go through this endpoint. There is no REST API.
Endpoints
| Environment | URL |
|---|---|
| Production | https://api.pay.accru.co/graphql |
| Sandbox | https://api.qa.pay.accru.co/graphql |
All requests use POST. The Content-Type must be application/json.
API scopes
AccruPay has two authentication scopes. Choose the right one based on where your code runs.
| Scope | Authentication | Used by |
|---|---|---|
| Merchant API | accrupay-api-secret header | Your backend server, Node SDK |
| Client Public API | merchantPublicId in query variables | Browser, React SDK |
The Merchant API requires your secret key and must never be called from the browser. The Client Public API is safe for frontend use — it uses your merchant public ID instead of a secret.
Authentication
Every Merchant API request must include:
accrupay-api-secret: YOUR_SECRET
Content-Type: application/json
Minimal curl example
curl -X POST https://api.pay.accru.co/graphql \
-H "Content-Type: application/json" \
-H "accrupay-api-secret: YOUR_SECRET" \
-d '{"query":"{ merchantApi { id name publicId } }"}'
With query variables
curl -X POST https://api.pay.accru.co/graphql \
-H "Content-Type: application/json" \
-H "accrupay-api-secret: YOUR_SECRET" \
-d '{
"query": "query GetTransactions($take: Int, $skip: Int) { merchantApiTransactions(take: $take, skip: $skip) { edges { node { id status amount } } totalCount } }",
"variables": { "take": 10, "skip": 0 }
}'
Never send your accrupay-api-secret from a browser, mobile app, or any client-side context. Create a backend route that proxies the operation if needed.
Custom scalars
The API uses two custom scalars that require special handling.
| Scalar | Wire format | Description |
|---|---|---|
BigInt | JSON number | Monetary amounts as integer minor units (e.g. 10000 = $100.00 USD) |
DateTimeISO | ISO 8601 string | All timestamps in UTC, e.g. "2024-01-15T12:00:00.000Z" |
BigInt values are transmitted as JSON numbers — they are large integers, not floats. Standard JavaScript JSON parsers lose precision for numbers above Number.MAX_SAFE_INTEGER. If you process large amounts server-side, use a BigInt-safe JSON parser such as json-bigint.
Pagination
All list operations support two pagination styles. Both can be used independently or together.
Offset pagination
Use skip and take for simple page-based navigation.
query ListTransactions {
merchantApiTransactions(
take: 20
skip: 40
) {
edges {
node {
id
amount
status
createdAt
}
}
totalCount
}
}
| Argument | Type | Description |
|---|---|---|
take | Int | Number of records to return (page size) |
skip | Int | Number of records to skip before the page starts |
Cursor pagination
Use after, before, first, and last for efficient traversal of large datasets.
query ListTransactionsCursor {
merchantApiTransactions(
first: 20
after: "eyJpZCI6IjEyMyJ9"
) {
edges {
node {
id
amount
status
}
cursor
}
pageInfo {
hasNextPage
hasPreviousPage
startCursor
endCursor
}
totalCount
}
}
| Argument | Type | Description |
|---|---|---|
first | Int | Return the first N items after the cursor |
after | String | Cursor from a previous page's edges[].cursor or pageInfo.endCursor |
last | Int | Return the last N items before the cursor (backward pagination) |
before | String | Cursor from a previous page's pageInfo.startCursor |
PageInfo fields
Every paginated response includes a pageInfo object.
| Field | Type | Description |
|---|---|---|
hasNextPage | Boolean! | Whether more records exist after this page |
hasPreviousPage | Boolean! | Whether more records exist before this page |
startCursor | String | Cursor pointing to the first record in this page |
endCursor | String | Cursor pointing to the last record in this page |
Connection shape
All list responses follow the Relay connection pattern:
{
edges {
node { ...fields }
cursor
}
pageInfo {
hasNextPage
hasPreviousPage
startCursor
endCursor
}
totalCount
}
Sorting
List operations that support sorting accept an orderBy argument.
query TransactionsSorted {
merchantApiTransactions(
take: 10
skip: 0
orderBy: { field: createdAt, direction: DESC }
) {
edges {
node {
id
createdAt
amount
}
}
totalCount
}
}
| Field | Values | Description |
|---|---|---|
field | Operation-specific | Field to sort by (e.g. createdAt, amount) |
direction | ASC | DESC | Ascending or descending order |
Error handling
GraphQL errors appear in the errors array. The HTTP status code is always 200 for valid GraphQL responses — inspect the errors field, not the HTTP status.
{
"errors": [
{
"message": "Unauthorized",
"extensions": {
"code": "UNAUTHENTICATED"
}
}
],
"data": null
}
Do not rely on HTTP status codes to detect API errors. Always check the errors array in the response body.
Next steps
- Enums — all enum values used across the API
- Transactions — list, refund, void, and sync transactions
- Sessions — start and verify payment sessions
- Payment Methods — list and manage stored payment methods