🏪 Merchant Initiated Transactions

Learn how to charge customers without their active participation using stored credentials from a previous authorization.

What is a Merchant Initiated Transaction?

A Merchant Initiated Transaction (MIT) uses payment credentials previously authorized by a customer to process payments without their active participation at the time of charge. This enables business models where charges occur based on usage, events, or merchant-determined timing.

📘 Key Difference from Card on File

Unlike Card on File transactions where the customer actively participates in each purchase, MIT transactions are initiated by the merchant without the customer being present or actively involved.

Key Characteristics

  • No Customer Participation: Charges are processed without the customer actively initiating payment
  • Prior Authorization Required: Customer must have previously authorized their card for MIT use
  • Merchant-Driven Timing: You control when charges occur based on your business logic
  • Unscheduled Charges: Ideal for variable amounts and timing (usage-based, threshold triggers, etc.)

MIT Compliance & Requirements

Card networks require specific handling for Merchant Initiated Transactions to protect consumers and ensure proper transaction categorization.

Compliance Requirements

Critical Compliance Steps

  1. Obtain explicit consent for storing credentials and processing future MIT charges
  2. Clearly disclose how, when, and why their card will be charged
  3. Provide terms that explain MIT usage (e.g., usage-based billing terms)
  4. Maintain records of customer consent for audit purposes
  5. Notify customers before each transaction commences

Coinflow handles the technical compliance, but you must obtain and document customer consent.

Use Cases for MIT

Usage-Based Billing

Charge customers based on consumption (API calls, storage, bandwidth, etc.)

Account Top-Ups

Automatically add funds when balance falls below threshold

Post-Service Charges

Bill for services after completion (ride-sharing, delivery tips, etc.)

Delayed Fulfillment

Charge when items ship or services are delivered


How It Works

1

Customer Authorizes Card

Customer completes an initial purchase or authorizes their card via a zero auth transaction and consents to future MIT charges on your platform.

2

Coinflow Stores MIT Credentials

The card details and MIT authorization reference are securely stored in Coinflow’s PCI-compliant vault.

3

You Trigger the Charge

When your business logic determines a charge is needed (usage threshold, billing cycle, etc.), you call the MIT endpoint.

4

Payment is Processed

Coinflow processes the payment using the stored credentials without requiring customer interaction.


Card on File vs. Subscriptions vs. Merchant Initiated Transactions

Understanding the differences between payment types helps ensure compliance and proper implementation:

FeatureCard on FileSubscriptionsMerchant Initiated (MIT)
InitiatorCustomerAutomaticMerchant
ScheduleOn-demandFixed recurringVariable
Customer PresentYesInitiallyNo
Use CaseRepeat purchasesRecurring billingUsage charges, top-ups
Consent RequiredPer transactionOnce, at signupOnce, with conditions

💡 Need Fixed Recurring Payments?

If you need automated payments on a fixed schedule (monthly, weekly, etc.), check out our Subscriptions Overview documentation.


Implementation Guide

Implementing Merchant Initiated Transactions is a two-step process:

  1. Initial Authorization - Store the customer’s card with MIT authorization
  2. Subsequent Charges - Process MIT payments as needed
1

Step 1: Authorize Card for MIT Use

One approach is to perform a zero authorization on the card to validate and store the card for MIT use. This authorizes the card for $0.00, establishing the credentials without charging the customer.

$POST /api/checkout/zero-authorization/{merchantId}

Request Body:

1{
2 "card": {
3 "number": "4111111111111111",
4 "expiryMonth": "12",
5 "expiryYear": "2025",
6 "cvv": "123"
7 }
8}

Or use a previously tokenized card:

1{
2 "token": "4111114324324111_bt"
3}

Save the Payment ID

After a successful Zero Authorization, save the paymentId from the response. You’ll use this as the originalPaymentId for subsequent MIT charges.

Alternative: Initial Purchase

You can also use a regular card payment as the original authorization. Any successful card transaction with CVV verification can be used as the originalPaymentId for MIT. This is useful when the customer is making an initial purchase and you want to enable future MIT charges.

Using a Saved Token:

$POST /api/checkout/card/{merchantId}
1{
2 "subtotal": {
3 "cents": 1500,
4 "currency": "USD"
5 },
6 "token": "4111114324324111_bt"
7}

Using a New Card:

1{
2 "subtotal": {
3 "cents": 1500,
4 "currency": "USD"
5 },
6 "card": {
7 "number": "4111111111111111",
8 "expiryMonth": "12",
9 "expiryYear": "2025",
10 "cvv": "123"
11 }
12}

Response:

1{
2 "paymentId": "550e8400-e29b-41d4-a716-446655440000"
3}

Save the Payment ID

Just like with Zero Authorization, save the paymentId from the checkout response. You’ll use this as the originalPaymentId for subsequent MIT charges. The initial purchase amount also establishes the baseline for maximum MIT charge calculations (based on your maxMultiple setting).

2

Step 2: Process Merchant Initiated Transactions

When your business logic determines a charge is needed, call the MIT endpoint with the original payment ID.

$POST /api/checkout/merchant-initiated-transaction

View MIT API Reference

Request Parameters:

ParameterRequiredDescription
subtotalYesThe amount to charge. Object with cents (integer) and currency (e.g., “USD”)
originalPaymentIdYesThe payment ID from the Zero Authorization or initial CVV-verified transaction
settlementTypeNoSpecify the payment settlement type (e.g., “USDC”, “Credits”, “Bank”)
webhookInfoNoCustom webhook data to be sent to your webhook endpoint if configured
presentmentNoThe currency to charge the customer’s card (e.g., “EUR”). If different from subtotal currency, conversion will be applied
statementDescriptorNoIf the bank supports dynamic descriptors, this text will appear on the customer’s statement
authOnlyNoOnly authorize the purchase without capturing. Default: false
feePercentageNoMarketplace fee percentage taken from subtotal (0-100). Used for seller/submerchant transactions
fixedFeeNoFixed amount marketplace fee taken from subtotal. Object with cents value
destinationAuthKeyNoJWT token for USDC settlement to addresses other than your main merchant settlement address
rentNo(Solana only) If your transaction requires a known amount of Rent to be paid. Object with lamports value
redemptionCheckNo(Solana only) If a transaction involved in the purchase should be checked for redemption
transactionDataNo(EVM only) Transaction request to execute on successful purchase. Gas fees are auto-calculated and added to the total
accountFundingTransactionNoAccount funding transaction details if applicable

Example Request:

1{
2 "subtotal": {
3 "cents": 2500,
4 "currency": "USD"
5 },
6 "originalPaymentId": "550e8400-e29b-41d4-a716-446655440000",
7 "settlementType": "USDC"
8}
3

Step 3: Handle the Response

A successful MIT returns the new payment ID:

1{
2 "paymentId": "650e8400-e29b-41d4-a716-446655440001"
3}

Complete Example

Option 1: Zero Authorization Flow

Here’s a complete example showing Zero Authorization followed by an MIT charge:

$curl --request POST \
> --url https://api-sandbox.coinflow.cash/api/checkout/zero-authorization/your-merchant-id \
> --header 'accept: application/json' \
> --header 'content-type: application/json' \
> --header 'x-user-id: customer-123' \
> --data '{
> "token": "4111114324324111_bt"
> }'
$curl --request POST \
> --url https://api-sandbox.coinflow.cash/api/checkout/merchant-initiated-transaction \
> --header 'accept: application/json' \
> --header 'content-type: application/json' \
> --header 'Authorization: your-merchant-api-key' \
> --header 'x-user-id: customer-123' \
> --data '{
> "subtotal": {
> "cents": 5000,
> "currency": "USD"
> },
> "originalPaymentId": "550e8400-e29b-41d4-a716-446655440000",
> "settlementType": "USDC"
> }'

Option 2: Initial Purchase Flow

Here’s a complete example showing an initial card purchase followed by an MIT charge:

$curl --request POST \
> --url https://api-sandbox.coinflow.cash/api/checkout/card/your-merchant-id \
> --header 'accept: application/json' \
> --header 'content-type: application/json' \
> --header 'x-user-id: customer-123' \
> --data '{
> "subtotal": {
> "cents": 2500,
> "currency": "USD"
> },
> "token": "4111114324324111_bt"
> }'
$curl --request POST \
> --url https://api-sandbox.coinflow.cash/api/checkout/merchant-initiated-transaction \
> --header 'accept: application/json' \
> --header 'content-type: application/json' \
> --header 'Authorization: your-merchant-api-key' \
> --header 'x-user-id: customer-123' \
> --data '{
> "subtotal": {
> "cents": 5000,
> "currency": "USD"
> },
> "originalPaymentId": "550e8400-e29b-41d4-a716-446655440000",
> "settlementType": "USDC"
> }'

Maximum MIT Amount

The maximum amount allowed for a MIT is determined by the maximum amount a customer has spent in a customer initiated transaction (CIT) where the customer provided the CVV.

However, default maximum amounts apply to customers without any transaction history but who have authorized their card via zero auth. Your Coinflow integration representative will configure this default for you.


Merchant Configuration Settings

Merchant Initiated Transactions include configurable settings that control how and when stored credentials can be used. These settings help manage security, fraud prevention, and compliance.

Configuration Required

MIT functionality must be enabled on your merchant account before you can process MIT payments. Contact your Coinflow integration representative to configure these settings.

Available Configuration Options

Your Coinflow integration team will configure the following MIT settings for your merchant account:

Velocity Controls:

  • maxCount - Maximum number of MIT payments allowed within a time period
  • period - Time window in seconds for the maxCount limit (e.g., 86400 for 24 hours)

For example, if I have a period of 90 seconds and a max count of 5, then I can only process 5 transactions for a given customer using a given originalPaymentId in 90 seconds. If I attempt more, then I will receive a 429 error.

Payment Limits:

  • maxMultiple - Maximum multiplier for MIT transaction amounts compared to the maximum historical payment amount
  • maxZeroAuthAmount - Default maximum amount for MIT when customer has no transaction history
  • maxAmountLookback - Time window to look back for maximum payment amount calculation

Examples

  1. If a customer has spent in CVV verified payments, 10.00,10.00, 6.00, 12.00,and12.00, and 40.00 and all of these payments fall in the maxAmountLookback time frame, then $40.00 will be used as the base maximum amount. This value will then be multiplied by the maxMultiple to determine the maximum amount that can be charged in a MIT.
  2. Let’s say a customer just signed up for your usage-billing based platform, and when they add a card you perform a zero authorization on that card where the user provides the CVV. Now you try to perform a MIT charging this user. The maximum amount they can be charged is the maxZeroAuthAmount multiplied by the maxMultiple.

Time-Based Restrictions:

  • expiration - Time window in seconds during which an originalPaymentId can be used for MIT

For example, if the expiration is 2 weeks, and the original payment (from originalPaymentId) is older than 2 weeks, then I can no longer use this as the originalPaymentId for a MIT. I must retrieve a newer CIT. Example flows could be a usage based billing platform where now I prompt the user to complete a payment manually where they enter in their CVV and then use that paymentId for subsequent MITs, or simply ask the customer to reauthorize their card with a zero authorization.

Example Configuration

1"enabled": true,
2"maxCount": 5,
3"period": 86400,
4"maxMultiple": 3,
5"expiration": 2592000,
6"maxZeroAuthAmount": { "cents": 2000 },
7"maxAmountLookback": 2592000

This configuration means:

  • ✅ MIT is enabled
  • ✅ Maximum 5 MIT payments per 24 hours per original authorization
  • ✅ MIT payments can be up to 3× the customer’s maximum historical payment
  • ✅ Original authorizations can be used for 30 days
  • ✅ Zero Authorization allows up to $20.00 × multiplier for MIT charges

Error Handling

Understanding and properly handling MIT errors is critical for a smooth implementation.

Common Error Codes

Error Message:

Merchant Initiated Transaction not enabled. Please contact your integrations representative.

Cause: MIT functionality is not enabled on your merchant account.

Resolution:

  • Contact your Coinflow integration representative to enable MIT
  • Once enabled, configure the appropriate settings for your use case

Error Message:

Cannot perform card on file operations for mobile wallet payments

Cause: You’re attempting to use a mobile wallet payment (Apple Pay, Google Pay) as the original authorization for MIT.

Resolution:

  • Mobile wallet payments cannot be used as MIT references
  • Use a regular card payment as the initial authorization
  • For mobile wallet payments, customers must authenticate each time (to be rectified soon)

Error Message:

Cannot perform card on file operations for a originalPaymentId which is a card on file transaction,
please pass the originalPaymentId which processed with the CVV Verification

Cause: You’re attempting to use an MIT or Card on File payment as the original authorization.

Resolution:

  • Only use the initial CVV-verified payment as the originalPaymentId
  • Do not chain MIT transactions
  • Always reference back to the original CVV-verified payment

Error Message:

Max number of Card-on-File payments reached. (X payments in Y seconds)

Cause: The customer has exceeded the maximum number of MIT payments allowed within the configured time period.

What This Means:

  • Too many MIT charges have been processed against this authorization
  • This is a security measure to prevent abuse
  • Based on your merchant’s maxCount and period settings

Resolution Options:

  1. Option A: Wait for Period Reset

    • Wait for the current period to expire
    • The counter resets after the configured period
  2. Option B: New Authorization

    • Have the customer re-authorize their card
    • Process a new Zero Authorization or card payment with CVV
    • Use this new payment ID for future MIT charges

Error Message:

This original payment can no longer be used as a card-on-file reference because it has exceeded
the allowed X-minute reference window.

Cause: Too much time has passed since the original authorization. The reference has expired based on your merchant’s expiration setting.

Resolution Options:

  1. Prompt Customer Re-Authorization
    • Have the customer perform a new Zero Authorization
    • Or complete a new card payment with CVV
    • Use this new payment ID for future MIT charges

Proactive Approach

Track when original authorizations are approaching expiration and prompt customers to re-authorize before it expires.

Error Message:

Amount exceeds limit: the total for a card-on-file transaction cannot exceed $X.XX (the allowed
multiplier of Y) of the original payment amount ($Z.ZZ).

Cause: The MIT payment amount exceeds the calculated maximum based on the customer’s payment history.

Example:

  • Maximum historical payment: $10.00
  • Multiplier setting: 3
  • Maximum allowed MIT: $30.00
  • Your request: $35.00 ❌

What This Means:

  • MIT charges are limited to prevent unexpectedly large charges
  • The limit is based on the customer’s maximum payment in the lookback period
  • If using Zero Authorization only, the limit is based on maxZeroAuthAmount × maxMultiple

Resolution

  1. Request Customer Authorization
    • For amounts significantly higher than historical payments
    • Have the customer complete a transaction with active participation where they enter their CVV

Error Handling Quick Reference

1async function processMerchantInitiatedTransaction(originalPaymentId, amount) {
2 try {
3 const response = await fetch(
4 '/api/checkout/merchant-initiated-transaction',
5 {
6 method: 'POST',
7 headers: {
8 'Content-Type': 'application/json',
9 Authorization: 'your-merchant-api-key',
10 'x-user-id': 'customer-123',
11 },
12 body: JSON.stringify({
13 subtotal: amount,
14 originalPaymentId: originalPaymentId,
15 }),
16 }
17 );
18
19 if (!response.ok) {
20 const error = await response.json();
21
22 switch (response.status) {
23 case 403:
24 // MIT not enabled
25 console.error('MIT not enabled for this merchant');
26 break;
27 case 410:
28 // Authorization expired or amount exceeded
29 return handleExpiredOrExceeded(error);
30 case 429:
31 // Rate limit exceeded
32 return handleRateLimitExceeded(error);
33 default:
34 throw new Error(error.message);
35 }
36 }
37
38 return await response.json();
39 } catch (error) {
40 console.error('MIT payment failed:', error);
41 throw error;
42 }
43}
44
45function handleExpiredOrExceeded(error) {
46 // Prompt customer for new authorization
47 console.log(
48 'Original authorization no longer valid, customer re-auth required'
49 );
50 // Redirect to re-authorization flow
51}

Best Practice

For MIT implementations, maintain a system to track authorization expiration dates and proactively refresh them before they expire. This ensures uninterrupted billing for usage-based services.


Best Practices

Provide clear, accessible terms explaining when and how the customer’s card will be charged. Include specifics about trigger conditions (usage thresholds, billing cycles, etc.) and estimated charge amounts.

For better customer experience and reduced disputes, send email or push notifications before processing MIT charges, especially for larger amounts or first-time charges.

Use idempotent request patterns to prevent duplicate charges in case of network issues or retries. Track MIT attempts with unique reference IDs.

Set up monitoring for MIT failures and velocity limit hits. Proactively reach out to customers whose authorizations are expiring or hitting limits.

After each MIT charge, send a detailed receipt explaining what was charged and why. Include a way for customers to review their usage or billing history.


Frequently Asked Questions

Card on File transactions require the customer to actively participate and authorize each payment at the point of sale. MITs are initiated by the merchant without customer involvement, based on prior authorization.

MIT is designed for unscheduled, variable charges. For fixed recurring payments, use our Subscription feature which is optimized for regular billing cycles with predictable amounts.

If the stored card expires, MIT charges will fail. You’ll need to prompt the customer to update their payment method and complete a new authorization.

No, MIT transactions are processed with the same fee structure as regular card transactions. There are no additional charges for using MIT functionality.

The MIT limit is based on the customer’s maximum historical payment multiplied by the configured multiplier. To increase the limit, have the customer complete a regular card payment (with CVV) at a higher amount.


Next Steps