PlusPayDevelopers

Error handling

Catch and interpret A2A errors and error codes.

Every operation either resolves with a typed response or fails with a typed error. On Flutter and React Native the error type is PPA2AException; on the native package it is PlusPayException. All of them expose an error code and a message.

FlutterReact NativeNative
TypePPA2AExceptionPPA2AExceptionPlusPayException
CodeerrorCodeerrorCodegetError_code()
MessagemessagemessagegetError_message()

Catching errors

try {
  final result = await _pluspay.startPayment(request);
  // success
} on PPA2AException catch (e) {
  print(e.errorCode); // e.g. "LAUNCH_INTENT_ERROR"
  print(e.message);   // human-readable message
}

Error codes

Branch on errorCode, never on the message text. Flutter (0.8.0+) and React Native (0.4.0+) also expose these codes as constants in PPA2AErrorCodes.

Returned by the client package

CodeMeaning
LAUNCH_INTENT_ERRORPOS+ could not be launched (not installed, or the intent could not be resolved).
PP-A2A-PARSEThe response from POS+ could not be parsed.
PP_A2A_015Another request from your app is still waiting for its result. Flutter 0.8.0+ and React Native 0.4.0+ reject the new request immediately, without launching POS+.
NOT_INITIALIZEDReact Native: initialize() was not called before the request.
TIMEOUTNative package: no response from POS+ within the client timeout.

Returned by POS+

CodeMeaning
PP-A2A-003The intent did not contain a request extra. Note the hyphens: this is not PP_A2A_003.
PP_A2A_001The request is empty.
PP_A2A_002This operation needs a data object, but it is missing or is not an object.
PP_A2A_003The client_token in the header is invalid (only checked when a token is sent).
PP_A2A_004Invalid end-of-day request: is_all is false but types is empty.
PP_A2A_005Invalid parameter request: is_all is false but types is empty.
PP_A2A_006Invalid request parameter.
PP_A2A_007Unexpected error while handling the request. The final state is unknown: query it with getTransactionResult / getOrderResult.
PP_A2A_008The header is missing.
PP_A2A_009transaction_type is missing or not a known operation.
PP_A2A_010A header field required by this operation is missing or empty (for example order_code or transaction_id).
PP_A2A_011Nobody has ever logged in to POS+ on this device. Log in to POS+ once, then retry.
PP_A2A_012The operation failed in POS+ (declined, cancelled by the user, order closed, …). The message describes the cause.
PP_A2A_013POS+ could not log in automatically. Check the device's internet connection and the POS+ session.
PP_A2A_014POS+ timed out: it could not get ready within 3 minutes, or the request did not finish within 15 minutes. The final state is unknown: query it.
PP_A2A_015POS+ is still processing an earlier request. Wait for that result, then retry.
PP_A2A_016TRANSACTION_RESULT: the order has no transaction with the given transaction_id.

error_message is always in Turkish, even when you set a locale. For example: "İşlem kullanıcı veya sistem tarafından iptal edildi!" ("The transaction was cancelled by the user or the system."). If you show errors to your users in another language, map errorCode to your own text.

Timeouts and concurrency

  • One request at a time. POS+ handles a single A2A request at a time. A second request that arrives while one is in progress is rejected with PP_A2A_015. Wait for the first result before you send the next request.
  • POS+ start-up: 3 minutes. If POS+ is launched by your request and cannot get ready to handle it within 3 minutes, it answers with PP_A2A_014.
  • Request handling: 15 minutes. If a request is not finished within 15 minutes, POS+ answers with PP_A2A_014. The limit is long on purpose so that a real payment flow (card reading, PIN entry, receipt) is never cut off.
  • Client-side timeouts. The Flutter and React Native packages don't time out on their own. If you add your own timeout, make it longer than 15 minutes. Otherwise a payment that completes in POS+ looks failed in your app.
  • After it sends the result, POS+ brings your app back to the foreground and moves itself to the background.
  • Treat any thrown error as a non-completed transaction. Do not assume the payment succeeded.
  • For PP_A2A_007 and PP_A2A_014, the outcome is unknown. Query it with getTransactionResult / getOrderResult before you retry.
  • For LAUNCH_INTENT_ERROR, verify POS+ is installed and (Flutter) consider providing fallbackPackageName / fallbackActivityName during initialization.
  • For PP_A2A_011 and PP_A2A_013, ask the user to open POS+ and log in.