Errors
The MPError enum and delegate-callback reference for Scan to PayKit.
Scan to PayKit reports failures in two layers: the delegate callback that fired (e.g. scanToPayError(_:) vs scanToPayPaymentFailed(...)) and, for the error callback specifically, the MPError enum value passed in.
Delegate callbacks vs MPError
| Layer | Where it shows up | How to read it |
|---|---|---|
| Delegate method | Which MPScanToPayDelegate method the SDK called | Tells you what kind of outcome occurred |
MPError enum | The argument passed to scanToPayError(_:) | Tells you the specific cause |
If scanToPayError(_:) fires, you'll have an MPError to inspect. For the other callbacks (success, failure, cancel, invalid code, registered, wallet completed), no MPError is involved.
MPScanToPayDelegate callbacks
| Callback | When you'll see it |
|---|---|
scanToPayPaymentSucceeded(withTransactionReference:) | Customer completed payment (verify server-side) |
scanToPayPaymentFailed(withTransactionReference:) | Payment was attempted but failed (bank declined, etc.) |
scanToPayUserDidCancel() | Customer aborted before completing |
scanToPayInvalidCode() | code parameter was malformed, expired, or already used |
scanToPayError(_:) | An error occurred — see MPError below |
scanToPayUserRegistered() | Pre-registration completed |
scanToPayUserCompletedWallet() | Manage-card flow completed |
MPError enum
typedef NS_ENUM(NSInteger, MPError) {
MPErrorNetworkError,
MPErrorExceptionOccurred,
MPErrorPaymentError,
MPErrorOTPError,
MPErrorInvalidCodeParameter,
MPErrorInvalidApiKeyParameter,
MPErrorSecureCodeNotSupported
};| Case | Description | What to do |
|---|---|---|
MPErrorNetworkError | The SDK couldn't reach the platform | Show a "no network" message; let the customer retry |
MPErrorExceptionOccurred | An unexpected internal exception | Raise a support ticket with details (capture timestamp) |
MPErrorPaymentError | Payment-time error not surfaced as scanToPayPaymentFailed | Treat like scanToPayPaymentFailed; let the customer retry |
MPErrorOTPError | OTP retrieval / validation failed during card registration | Customer can re-request the OTP |
MPErrorInvalidCodeParameter | code parameter was missing or empty | Fix the calling code — code is mandatory |
MPErrorInvalidApiKeyParameter | apiKey parameter was missing or invalid | Generate a fresh key in the Portal; verify the system (.live vs .test) |
MPErrorSecureCodeNotSupported | The card's BIN requires 3D Secure but isn't enabled for it | Customer needs a different card, or the BIN config needs platform support |
Triage cheat sheet
delegate callback?
├── scanToPayPaymentSucceeded(...) → verify on backend, fulfil order
├── scanToPayPaymentFailed(...) → log reference, retry option
├── scanToPayUserDidCancel() → noop or analytics
├── scanToPayInvalidCode() → bug in your code-creation flow
├── scanToPayUserRegistered() → onboarding complete
├── scanToPayUserCompletedWallet() → manage flow done
└── scanToPayError(MPError)
├── .networkError → retry, friendly message
├── .exceptionOccurred → support ticket
├── .paymentError → retry payment
├── .otpError → retry OTP
├── .invalidCodeParameter → integration bug
├── .invalidApiKeyParameter → integration bug
└── .secureCodeNotSupported → unsupported card
What's next
- Test cards that produce specific errors → Sandbox and test cards
- Confirm a transaction's true outcome → Webhooks / Querying transactions
- Bank decline codes (when
scanToPayPaymentFailed) → ISO response codes - Support escalation → Support
Updated 2 days ago
