Skip to main content

Errors

AccruPay uses the standard GraphQL error envelope for all API-level failures. Transaction declines are a separate concern and are not represented as GraphQL errors.


GraphQL error envelope

When an operation fails at the API level, the response includes an errors array and data is null (or the failing field is null).

{
"errors": [
{
"message": "Authentication error.",
"extensions": {
"code": "UNAUTHORIZED"
}
}
],
"data": null
}

The extensions.code field is the machine-readable error code. Always branch on extensions.code, not on message — message text may change without notice.


extensions.code values

extensions.code is one of the fixed framework codes below, or a namespaced AppError key (@domain/REASON) for business-rule failures.

CodeTriggersRecommended action
UNAUTHORIZEDMissing or invalid accrupay-api-secret headerVerify the API secret is set correctly and is not expired
FORBIDDENValid credentials but insufficient permissions for the requested resourceCheck that the API key belongs to the correct merchant account and has access to the requested operation
GRAPHQL_VALIDATION_FAILEDA required argument is missing, or a value is out of range / fails format validationCheck the message field for field-level detail; fix the input and retry
GRAPHQL_PARSE_FAILEDThe GraphQL document is malformedFix the query syntax
@domain/REASON (AppError key)A business rule was violated (e.g. resource not found, duplicate merchantInternalTransactionCode, provider not resolvable)The key names the reason; read message and correct the request
INTERNAL_SERVER_ERRORUnexpected server-side failureRetry with exponential backoff; if the issue persists, contact AccruPay support with the full error response

Transaction declines are not API errors

warning

A payment that is declined or fails at the provider level does not produce a GraphQL errors entry. The mutation resolves successfully and returns a transaction object. You must check transaction.status in the response data.

{
"data": {
"merchantApiServerPaymentMethodTransactionCreate": {
"id": "txn-uuid",
"status": "DECLINED",
"providerError": "Insufficient funds"
}
}
}

Transaction terminal statuses

StatusMeaningWhat to show the customer
SUCCEEDEDPayment completed successfullyConfirmation — order fulfilled
DECLINEDCard network or issuer declined the chargeAsk the customer to try a different payment method
FAILEDProvider-side processing failure (e.g. timeout, invalid card data)Generic error — try again or contact support
CANCELEDAuthorization was released without captureNo charge was made
SUCCEEDED (action: REFUND)Refund processedConfirm refund amount in refundedAmount field

Check the providerError field for the raw decline reason returned by the provider. This is useful for logging and support, but should not be shown verbatim to customers.


providerError field

Most transaction return types include a providerError field:

{
id
status
providerError
}

providerError is populated when status is DECLINED or FAILED. It contains the provider's raw reason string (e.g. "Do not honor", "Insufficient funds", "Invalid card number").

Use providerError for:

  • Internal logging and alerting
  • Support ticket context
  • Reconciliation when a statement entry is unclear

Do not expose providerError directly to end customers. Map it to a user-friendly message in your application layer.


Network errors vs GraphQL errors

HTTP-level failures (5xx, network timeouts, DNS failures) do not produce a GraphQL errors array — the response body may be empty or non-JSON. Handle these separately:

ScenarioBehaviorRecommendation
HTTP 200 with errors[]GraphQL error — parseable JSONBranch on extensions.code
HTTP 200 with dataSuccessful responseCheck transaction.status for declines
HTTP 401Authentication rejected at the HTTP layer before GraphQLSame as UNAUTHORIZED — check the API secret
HTTP 5xxServer error before GraphQL processingRetry with backoff
Network timeout / no responseTransport-level failureRetry; use merchantInternalTransactionCode as idempotency key to avoid duplicate charges

Idempotency and retries

merchantInternalTransactionCode is your idempotency key for charge mutations. If a request times out and you are unsure whether it was processed, do not retry with a new code — first query the transaction by merchantInternalTransactionCode to check whether it was created.