This document provides a comprehensive testing checklist to ensure your integration handles all payment scenarios correctly before going live.
Before running tests, ensure you have:
| Category | Tests | Priority |
|---|---|---|
| Happy Path | 8 | Critical |
| Pre-Authorization & Capture | 6 | Critical |
| Void/Cancel Operations | 4 | High |
| Refund Scenarios | 5 | High |
| Error Handling | 12 | Critical |
| 3DS Scenarios | 5 | Critical |
| Webhook Integration | 8 | Critical |
| Edge Cases | 7 | Medium |
| External Integrations | 4 | Conditional |
| Security & Compliance | 6 | Critical |
Total: 65 test cases
Test Card:4000000000001091 (3DS required)
| Step | Action | Expected Result |
|---|---|---|
| 1 | Create client | Returns client ID |
| 2 | Create purchase (amount: 10000, force_recurring: true) | Returns purchase ID and direct_post_url |
| 3 | Submit card data with browser fingerprint | Returns 3DS parameters or ready status |
| 4 | Complete 3DS challenge | Redirects to callback URL |
| 5 | POST to callback with MD and PaRes | Returns success |
| 6 | Verify purchase status | Status: "paid" |
| 7 | Check for token | payment_method_details.card.token present |
| 8 | Check for network_transaction_id | Value present for MIT use |
Test Card:4000000000001000 (No 3DS)
| Step | Action | Expected Result |
|---|---|---|
| 1 | Create client | Returns client ID |
| 2 | Create purchase | Returns purchase ID |
| 3 | Submit card data | No 3DS parameters returned |
| 4 | Charge purchase | Status: "paid" |
Test Card:4000000000001091
| Step | Action | Expected Result |
|---|---|---|
| 1 | Create client | Returns client ID |
| 2 | Create purchase with amount: 0 | Returns purchase ID |
| 3 | Submit card data | 3DS flow initiated |
| 4 | Complete 3DS | Success |
| 5 | Verify no charge | Amount authorized: 0 |
| 6 | Verify token generated | Token present (if force_recurring: true) |
Prerequisite: Completed CIT with token stored
| Step | Action | Expected Result |
|---|---|---|
| 1 | Create MIT purchase with token reference | Returns purchase ID |
| 2 | Include previous_network_transaction_id | Accepted |
| 3 | Include original_amount_cents | Accepted |
| 4 | Submit with stored token (no CVV) | Ready for charge |
| 5 | Charge purchase | Status: "paid" |
| 6 | Verify no 3DS required | No 3DS challenge |
Test Card:5555555555554444
| Step | Action | Expected Result |
|---|---|---|
| 1 | Complete standard flow | Success |
| 2 | Verify card brand in response | brand: "mastercard" |
| Step | Action | Expected Result |
|---|---|---|
| 1 | Create purchase with multiple products | Total calculated correctly |
| 2 | Complete payment | Full amount charged |
| Step | Action | Expected Result |
|---|---|---|
| 1 | Create purchase with metadata | Accepted |
| 2 | Complete payment | Success |
| 3 | Retrieve purchase | Metadata preserved |
| 4 | Receive webhook | Metadata included |
| Step | Action | Expected Result |
|---|---|---|
| 1 | Create purchase with USD currency | Accepted |
| 2 | Complete payment | Charged in USD |
Test Card:4000000000001091
| Step | Action | Expected Result |
|---|---|---|
| 1 | Create purchase (amount: 50000) | Returns purchase ID |
| 2 | Submit card and complete 3DS | Authorization successful |
| 3 | Verify status | Status: "authorized" |
| 4 | Capture full amount | Status: "paid" |
| 5 | Verify captured amount | amount: 50000 |
| Step | Action | Expected Result |
|---|---|---|
| 1 | Create and authorize (amount: 50000) | Status: "authorized" |
| 2 | Capture partial amount (35000) | Status: "paid" |
| 3 | Verify captured amount | amount: 35000 |
| 4 | Verify remaining released | No hold for remaining 15000 |
| Step | Action | Expected Result |
|---|---|---|
| 1 | Authorize 100000 | Status: "authorized" |
| 2 | First capture: 30000 | Success, remaining: 70000 |
| 3 | Second capture: 40000 | Success, remaining: 30000 |
| 4 | Third capture: 30000 | Success, fully captured |
| 5 | Fourth capture attempt | Error: nothing remaining |
Prerequisite: Stored token from previous CIT
| Step | Action | Expected Result |
|---|---|---|
| 1 | Create purchase with is_recurring: true | Accepted |
| 2 | Submit with token, CVV: "000" | Accepted |
| 3 | Authorization completes | Status: "authorized" |
| 4 | Capture | Status: "paid" |
| Step | Action | Expected Result |
|---|---|---|
| 1 | Authorize 50000 | Status: "authorized" |
| 2 | Attempt capture of 60000 | Error: capture_amount_exceeds_authorization |
| Step | Action | Expected Result |
|---|---|---|
| 1 | Note: May require waiting or test mode | — |
| 2 | Attempt capture on expired auth | Error: authorization_expired |
| 3 | Verify appropriate error handling | User-friendly message |
| Step | Action | Expected Result |
|---|---|---|
| 1 | Create and authorize purchase | Status: "authorized" |
| 2 | Call cancel endpoint | Status: "cancelled" |
| 3 | Verify funds released | No hold on card |
| 4 | Attempt capture after void | Error: already_voided |
| Step | Action | Expected Result |
|---|---|---|
| 1 | Complete payment | Status: "paid" |
| 2 | Void same day | Status: "cancelled" |
| 3 | Verify immediate reversal | Funds released |
| Step | Action | Expected Result |
|---|---|---|
| 1 | Attempt void on settled transaction | Error: void_not_permitted |
| 2 | Verify error message | Suggests using refund |
| Step | Action | Expected Result |
|---|---|---|
| 1 | Process refund | Refund ID returned |
| 2 | Void refund same day | Success |
| 3 | Verify original charge intact | Full amount charged |
| Step | Action | Expected Result |
|---|---|---|
| 1 | Complete payment (29900) | Status: "paid" |
| 2 | Request full refund | Status: "refunded" |
| 3 | Verify refund amount | amount: 29900 |
| 4 | Receive webhook | Event: purchase.refunded |
| Step | Action | Expected Result |
|---|---|---|
| 1 | Complete payment (50000) | Status: "paid" |
| 2 | Request partial refund (20000) | Success |
| 3 | Verify remaining | 30000 still charged |
| 4 | Verify refund details | Refund ID, amount: 20000 |
| Step | Action | Expected Result |
|---|---|---|
| 1 | Complete payment (100000) | Status: "paid" |
| 2 | First refund (25000) | Success, remaining: 75000 |
| 3 | Second refund (25000) | Success, remaining: 50000 |
| 4 | Third refund (50000) | Success, remaining: 0 |
| 5 | Fourth refund attempt | Error: nothing to refund |
| Step | Action | Expected Result |
|---|---|---|
| 1 | Complete payment (30000) | Status: "paid" |
| 2 | Request refund (40000) | Error: exceeds original |
| Step | Action | Expected Result |
|---|---|---|
| 1 | Complete payment (50000) | Status: "paid" |
| 2 | First refund (30000) | Success |
| 3 | Second refund (30000) | Error: exceeds remaining |
Test Card:4000000000000002
| Step | Action | Expected Result |
|---|---|---|
| 1 | Submit declined card | Error returned |
| 2 | Verify error code | do_not_honour |
| 3 | Verify user-friendly message | Appropriate message |
Test Card:4000000000000069
| Step | Action | Expected Result |
|---|---|---|
| 1 | Submit expired card | Error: expired_card |
| 2 | Verify message | "Card has expired" |
| Step | Action | Expected Result |
|---|---|---|
| 1 | Submit card with insufficient funds | Error: insufficient_funds |
| 2 | Verify soft decline | Can retry later |
Test Card:4000000000000127
| Step | Action | Expected Result |
|---|---|---|
| 1 | Submit with wrong CVC | Error: cvc_check_failed |
Test Input:4111111111111112 (fails Luhn)
| Step | Action | Expected Result |
|---|---|---|
| 1 | Submit invalid card number | Error: invalid_card_number |
| 2 | Verify validation message | Clear error message |
| Step | Action | Expected Result |
|---|---|---|
| 1 | Submit wrong format | Error: invalid_expires |
| 2 | Test: "2028/12", "1228" | All fail |
| 3 | Correct: "12/28" | Success |
Test Card:4000000000000119
| Step | Action | Expected Result |
|---|---|---|
| 1 | Trigger processing error | Error returned |
| 2 | Verify retry logic | Exponential backoff |
| Step | Action | Expected Result |
|---|---|---|
| 1 | Submit without client_id | Validation error |
| 2 | Submit without brand_id | Validation error |
| 3 | Submit without currency | Validation error |
| 4 | Submit without products | Validation error |
| Step | Action | Expected Result |
|---|---|---|
| 1 | Use invalid API key | HTTP 401 |
| 2 | Use wrong key type | Error returned |
| 3 | Use expired key | HTTP 401 |
| Step | Action | Expected Result |
|---|---|---|
| 1 | Simulate network timeout | Error caught |
| 2 | Verify retry logic | Retries with backoff |
| 3 | Verify idempotency | No duplicate charges |
| Step | Action | Expected Result |
|---|---|---|
| 1 | Submit charge request | Success |
| 2 | Resubmit same request | Idempotent response |
| 3 | Verify only one charge | Single transaction |
| Step | Action | Expected Result |
|---|---|---|
| 1 | Create purchase | Get direct_post_url |
| 2 | Use URL once | Success |
| 3 | Reuse URL | Error: expired |
Test Card:4000000000001091
| Step | Action | Expected Result |
|---|---|---|
| 1 | Submit card requiring 3DS | 3DS parameters returned |
| 2 | Verify 3DS fields | MD, PaReq, URL, callback_url |
| 3 | Redirect to 3DS URL | Bank page loads |
| 4 | Complete challenge | Redirects to callback |
| 5 | Submit callback | Payment completes |
| Step | Action | Expected Result |
|---|---|---|
| 1 | Initiate 3DS | Challenge presented |
| 2 | Fail authentication | Error: 3ds_authentication_failed |
| 3 | Verify retry available | Can retry |
| Step | Action | Expected Result |
|---|---|---|
| 1 | Initiate 3DS | Challenge presented |
| 2 | Allow timeout | Error: timeout |
| 3 | Verify graceful handling | User-friendly message |
Test Card:4000000000001000
| Step | Action | Expected Result |
|---|---|---|
| 1 | Submit low-risk transaction | No challenge |
| 2 | Verify frictionless | Success without redirect |
| Step | Action | Expected Result |
|---|---|---|
| 1 | Complete 3DS transaction | Success |
| 2 | Verify ECI value | Present |
| 3 | Verify CAVV | Present |
| Step | Action | Expected Result |
|---|---|---|
| 1 | Complete payment | Webhook received |
| 2 | Verify event type | purchase.paid |
| 3 | Verify payload | All fields present |
| 4 | Verify purchase_id | Matches transaction |
| Step | Action | Expected Result |
|---|---|---|
| 1 | Submit declined card | Payment fails |
| 2 | Receive webhook | purchase.payment_failure |
| 3 | Verify error details | Error code included |
| Step | Action | Expected Result |
|---|---|---|
| 1 | Process refund | Completes |
| 2 | Receive webhook | purchase.refunded |
| 3 | Verify details | Amount, refund_id |
| Step | Action | Expected Result |
|---|---|---|
| 1 | Complete pre-auth | Holds funds |
| 2 | Receive webhook | purchase.authorized |
| 3 | Verify details | Amount, expiry |
| Step | Action | Expected Result |
|---|---|---|
| 1 | Receive webhook | Headers present |
| 2 | Verify signature | Matches computed |
| 3 | Verify timestamp | Within 5 minutes |
| 4 | Process webhook | Success |
| Step | Action | Expected Result |
|---|---|---|
| 1 | Receive tampered webhook | — |
| 2 | Verify signature | Mismatch detected |
| 3 | Reject webhook | HTTP 401 |
| 4 | No processing | No action taken |
| Step | Action | Expected Result |
|---|---|---|
| 1 | Receive webhook | Process |
| 2 | Receive same again | Detect duplicate |
| 3 | Return HTTP 200 | Acknowledge |
| 4 | Do not reprocess | Idempotent |
| Step | Action | Expected Result |
|---|---|---|
| 1 | Simulate timeout | Precium retries |
| 2 | Fix endpoint | Next retry succeeds |
| 3 | Verify no data loss | Event processed |
| Step | Action | Expected Result |
|---|---|---|
| 1 | Create purchase (amount: 1) | Accepted |
| 2 | Complete payment | Success |
| Step | Action | Expected Result |
|---|---|---|
| 1 | Create large purchase | Accepted or limit error |
| 2 | Verify handling | Appropriate response |
| Step | Action | Expected Result |
|---|---|---|
| 1 | Name with accents | Handled |
| 2 | Special characters | Handled |
| 3 | Verify encoding | UTF-8 preserved |
| Step | Action | Expected Result |
|---|---|---|
| 1 | Use expired token | Error: token_expired |
| 2 | Verify handling | Prompts re-tokenization |
| Step | Action | Expected Result |
|---|---|---|
| 1 | Send multiple simultaneous | All handled |
| 2 | Verify no race conditions | No duplicates |
| 3 | Verify data integrity | All correct |
| Step | Action | Expected Result |
|---|---|---|
| 1 | Create client once | ID stored |
| 2 | Use for multiple purchases | All succeed |
| 3 | Verify consistency | Data unchanged |
| Step | Action | Expected Result |
|---|---|---|
| 1 | Minimal fingerprint | Accepted |
| 2 | Full fingerprint | Accepted |
| 3 | Missing optional fields | Handled |
Complete if using external 3DS or network tokens
| Step | Action | Expected Result |
|---|---|---|
| 1 | Complete 3DS with MPI | Auth data obtained |
| 2 | Create purchase (is_external_3DS: true) | Accepted |
| 3 | Include CAVV, ECI, transaction ID | Validated |
| 4 | Complete payment | Success |
| Step | Action | Expected Result |
|---|---|---|
| 1 | Submit invalid CAVV | Error |
| 2 | Submit missing fields | Error |
| 3 | Submit wrong ECI format | Error |
| Step | Action | Expected Result |
|---|---|---|
| 1 | Submit network token | Accepted |
| 2 | Include cryptogram | Validated |
| 3 | Complete payment | Success |
| Step | Action | Expected Result |
|---|---|---|
| 1 | Submit expired cryptogram | Error |
| 2 | Verify handling | Prompts refresh |
| Step | Action | Expected Result |
|---|---|---|
| 1 | Check client-side code | Keys not exposed |
| 2 | Check logs | Keys masked |
| 3 | Verify HTTPS only | No HTTP |
| Step | Action | Expected Result |
|---|---|---|
| 1 | Check logs | Card numbers masked |
| 2 | Check storage | CVV not stored |
| 3 | Check URLs | Card data in POST only |
| Step | Action | Expected Result |
|---|---|---|
| 1 | Verify encryption | Encrypted at rest |
| 2 | Verify access control | Auth required |
| 3 | Verify UI | Tokens masked |
| Step | Action | Expected Result |
|---|---|---|
| 1 | Verify HTTPS | HTTP rejected |
| 2 | Verify signature | Invalid rejected |
| 3 | Verify timestamp | Old rejected |
| Step | Action | Expected Result |
|---|---|---|
| 1 | Check errors | No sensitive data |
| 2 | Check responses | No internal details |
| 3 | Check customer messages | Generic/friendly |
| Step | Action | Expected Result |
|---|---|---|
| 1 | Exceed rate limits | HTTP 429 |
| 2 | Verify backoff | Implements retry |
| 3 | Verify recovery | Resumes normally |
| Card Number | Brand | 3DS | Behavior |
|---|---|---|---|
4000000000001091 | Visa | Yes | Success with 3DS |
4000000000001000 | Visa | No | Success without 3DS |
5555555555554444 | Mastercard | Yes | Success |
| Card Number | Error Code | Description |
|---|---|---|
4000000000000002 | do_not_honour | Generic decline |
4000000000000069 | expired_card | Expired card |
4000000000000127 | cvc_check_failed | Invalid CVC |
4000000000000119 | processing_error | Processing error |
| CVC | Behavior |
|---|---|
123 | Success |
000 | Bypass (recurring) |
Use any future date in MM/YY format. Recommended: 12/28
Before going live, ensure: