Merchant-initiated flows

Certification cases for MIT Async Purchase, MIT Async Authorize, and Sync MIT.

Part of the Certification guide. Mark your scope on that page before you run these cases. Base payloads and test cards are on the Reference page.


5. MIT Async Purchase

Applies to: MIT-ASYNC-PURCHASE. /evaluate returns SUBMITTED; the outcome arrives by webhook. Hold the merchant order pending, not paid and not declined, and pause your own retries until a terminal event arrives. When a webhook is missed, GET /v1/orders/{id} returns the same numeric status and statusName as the event. The base MIT payload omits expiryDateUtc, so MIT-ASYNC-PURCHASE-01 also proves that the default expiry configured for the merchant is applied.

Reference: Workflows §2.3, Webhooks, GET /orders/{id}, Appendix A.2.

IDScenarioSetup / actionExpected resultEvidence
MIT-ASYNC-PURCHASE-01SubmittedBase MIT payloadHTTP 200; result Success; status SUBMITTED; orderId present. GET /v1/orders/{orderId} returns status 0 Draft or 4 ProcessingorderId
MIT-ASYNC-PURCHASE-02Rescue approvedWait for the MIT-ASYNC-PURCHASE-01 order to resolveorder.completed received; GET /v1/orders/{orderId} returns status 7 CompletedWebhook IdempotencyKey
MIT-ASYNC-PURCHASE-03Rescue declinedBase MIT payload with card 4012888888881881order.cancelled received; GET /v1/orders/{orderId} returns status 2 CancelledWebhook IdempotencyKey
MIT-ASYNC-PURCHASE-04Rescue window expiresBase MIT payload with expiryDateUtc set 15 minutes in the futureorder.expired received after the window; GET /v1/orders/{orderId} returns status 2 CancelledWebhook IdempotencyKey
MIT-ASYNC-PURCHASE-05Expiry beyond 21 daysBase MIT payload with expiryDateUtc set 30 days in the futureHTTP 400 with an errors object naming expiryDateUtctraceId
📘

Onhold is a pending state

Onhold (status 1) can appear on GET /v1/orders/{id} when the merchant processing cap is reached. No webhook is sent for it; the order resumes on its own. Treat it as pending.


6. MIT Async Authorize

Applies to: MIT-ASYNC-AUTHORIZE. Same payload as MIT Async Purchase with transactionType: "AUTHORIZATION". The approval arrives as order.capturerequired, and you must call /capture within the capture window. Run the capture cases in Section 8 and the cancel cases in Section 9 after this section.

Reference: Workflows §2.4, /capture, Appendix A.2, Appendix A.3.

IDScenarioSetup / actionExpected resultEvidence
MIT-ASYNC-AUTHORIZE-01SubmittedBase MIT payload with transactionType AUTHORIZATIONHTTP 200; status SUBMITTED; orderId presentorderId
MIT-ASYNC-AUTHORIZE-02Capture requiredWait for the MIT-ASYNC-AUTHORIZE-01 order to resolveorder.capturerequired received; GET /v1/orders/{orderId} returns status 5 CapturerequiredWebhook IdempotencyKey
MIT-ASYNC-AUTHORIZE-03Capture on receiptPOST /v1/capture for the full amount within the capture window after MIT-ASYNC-AUTHORIZE-02HTTP 200; status SUCCESS; GET returns status 7 Completed; totalBalancePaid equals the authorized amount; order.completed receivedorderId
MIT-ASYNC-AUTHORIZE-04DeclinedBase MIT payload with transactionType AUTHORIZATION and card 4012888888881881order.cancelled received; GET returns status 2 CancelledWebhook IdempotencyKey
MIT-ASYNC-AUTHORIZE-05Capture after the windowRepeat MIT-ASYNC-AUTHORIZE-01 and MIT-ASYNC-AUTHORIZE-02, wait longer than the capture window, then captureHTTP 400; no funds captured. order.expired received; GET returns status 2 CancelledCapture response, webhook IdempotencyKey

7. Sync MIT

Applies to: SYNC-MIT. The first /evaluate always returns DECLINED. Each later retry for the same merchant orderId returns DECLINED until the rescue lands, then APPROVED. The retry that returns APPROVED performs the capture. The rescue window is configured per account in hours from the decline, and the cutoff is hard. Ask your Solutions engineer how the sandbox resolves the rescue for this flow before running SYNC-MIT-03.

Three integration rules apply to this flow. Every retry carries the same merchant orderId and an attemptCount that increases by 1. FlexFactor must be the only retry mechanism during the rescue window: no other retry engine, cascade, re-authorization, or account updater runs for the merchant. At least 1 merchant retry must fall inside the window, or the integration must capture on order.capturerequired as in SYNC-MIT-04.

Reference: Workflows §2.5, Appendix A.2.

IDScenarioSetup / actionExpected resultEvidence
SYNC-MIT-01Initial call declinedBase MIT payload, expiryDateUtc omittedHTTP 200; status DECLINEDResponse body
SYNC-MIT-02Retry during processingRepeat SYNC-MIT-01 with the same merchant orderId, the same amount, the same payment method, and attemptCount increased by 1, before the rescue landsHTTP 200; status DECLINED. GET /v1/orders?query={merchant orderId} returns exactly 1 orderOrder count
SYNC-MIT-03Retry captures the rescueRepeat the SYNC-MIT-01 request after the rescue landsHTTP 200; status APPROVED; orderId present. GET /v1/orders/{orderId} returns status 7 CompletedorderId
SYNC-MIT-04Webhook backstop with explicit captureRepeat SYNC-MIT-01. On order.capturerequired, call POST /v1/capture for the full amount instead of waiting for the next retryHTTP 200; status SUCCESS; GET returns status 7 CompletedorderId, webhook IdempotencyKey
SYNC-MIT-05Window expiresRepeat SYNC-MIT-01 and send no further call until the configured window has passed, then retryHTTP 200; status DECLINED; order.expired received; GET returns status 2 CancelledWebhook IdempotencyKey


Did this page help you?