Ways to pay

Visa CARD

Visa CARD lets an InFlow buyer pay with an eligible linked Visa card using a verified spending allowance. Your application receives an encrypted credential for the purchase, not the underlying card number. The seller accepts that credential through MPP’s card method.

How Visa CARD payments work

Start with a card saved in the buyer’s InFlow account. Its Visa Intelligent Commerce (VIC) allowance specifies how much spending the cardholder permits and when that permission expires. The dashboard calls this a VIC Allowance.

  • The seller returns an MPP CARD challenge containing the purchase price, merchant information, and an encryption key.
  • The buyer selects that offer and a linked Visa card. InFlow checks the card and its allowance, then applies the buyer’s payment approval process.
  • After approval, InFlow obtains an encrypted payment credential through its Visa integration. The buyer SDK returns or submits that credential without decrypting it.
  • The seller processes the credential. After payment succeeds, the seller returns a payment receipt and the purchased result.

These steps have different outcomes. A verified allowance permits card use. An approved purchase permits credential creation. A ready credential can be submitted for payment. None of those states alone proves that the seller has received payment or delivered the purchase.

CARD is separate from ordinary linked-card payments and Stripe Shared Payment Token payments. It also does not replace service authentication or trusted agent verification.

Before you begin

Visa CARD uses MPP method card with intent charge. The seller advertises a CARD offer for the resource, and the buyer selects that offer. See Choose payment options for selecting an advertised payment option.

CARD is its own payment method, separate from the instrument rail of the inflow method. Configure the CARD method in both the buyer and seller applications.

  • The buyer needs an enabled, unexpired Visa card linked through InFlow’s supported card setup, with a verified USD allowance sufficient for the purchase.
  • An InFlow seller needs a connected Stripe account that can accept payments, plus complete Seller business details.
  • Both applications need the appropriate InFlow API keys and environment configuration. They do not need InFlow’s Basis Theory or Stripe secret keys.

Use Accounts and environments to configure the buyer and seller for the same environment.

Prepare the seller

Sign in to the InFlow Seller account and open Sandbox Stripe settings or production Stripe settings. Connect the intended Stripe account and confirm that Payments is Enabled. Complete Seller business details with the business name, website, and country. These identify the merchant receiving the payment, not the buyer.

The MPP Stripe Profile shown on that dashboard belongs to the separate Stripe payment method. It is not the merchant setup for CARD. Follow the CARD requirements here rather than assuming both methods have identical prerequisites.

Offer a one-time USD charge of at least $0.50, in whole cents. The following fragments use $1.00 and adapt the protected route in Accept MPP. Keep its signing secret, payment acceptance, receipt handling, and client lifecycle. These are configuration fragments, not standalone servers.

Replace the Go route’s offer with this CARD offer. Pass it to the same protected route’s Offers list.

offer := seller.Offer{Card: &seller.CardOffer{
    Amount: "1.00",
}}

In Node.js, await the CARD factory during setup. Here, apiKey is the Seller API key and secretKey is the application’s signing secret. Use the resulting charge middleware before the report handler.

import { Mppx } from 'mppx/express';
import { card, paymentHttpTransport } from '@inflowpayai/mpp-seller';

const payments = Mppx.create({
  methods: [await card({ apiKey, environment: 'sandbox' })],
  secretKey,
  transport: paymentHttpTransport(),
});
const charge = payments.charge({ amount: '1.00' });

In Python’s asynchronous application setup, create a CARD Seller and prepare the terms. Use these terms with the existing payment decorator. Keep the client open while serving requests and close it at shutdown.

seller = await Seller.create(
    ClientOptions(api_key=api_key, environment="sandbox"),
    method="card",
)
terms = seller.card_request({"amount": "1.00"})

In Rust, create a CARD offer using your initialized Sandbox Seller client. Use this offer in the existing Axum handler that issues challenges, accepts payment, and returns the receipt.

let offer = seller.offer(
    Method::Card,
    json!({"amount": "1.00"}),
    ChallengeOptions::default(),
)?;

These builders take decimal dollars and load merchant and encryption settings from InFlow’s seller configuration. Do not hardcode encryption keys or merchant account IDs. These examples configure one-time payments, not subscriptions or metered payments.

Link a Visa card and create its allowance

Open Instruments in the buyer’s InFlow dashboard and follow Link and choose a card. For an eligible linked Visa card, select VIC Allowance. If that control is absent, do not assume an ordinary saved instrument can be used for CARD.

  • Select Create Allowance. Enter a USD amount, a future expiration, and a description of the spending you permit. The expiration uses your account’s timezone.
  • Submit the form and inspect the allowance status. Creating the allowance does not charge the card.
  • If the status is Awaiting Visa verification, select Complete Verification. Follow the instructions in the secure window; Visa may request a verification code or a passkey.
  • Confirm that the status is Ready and Available (USD) covers the intended purchase. The card must also remain enabled and unexpired.

The allowance created here permits spending across merchants within its amount and expiration. It is not a per-seller budget or a recurring monthly allowance. Use Policies for the separate InFlow account rules. An allowance does not bypass the payment approval process.

Available allowance is permission to issue credentials, not money deposited in an InFlow balance. Issuing a credential consumes capacity even if the buyer never submits it or the payment is declined. Do not create credentials speculatively for purchases you may not make.

When setup has not completed

Creation unconfirmed means the creation result is unknown. Select Check Status before attempting another setup. Retry Request reuses the original request identifier; it is not a separate allowance request. For Setup failed, refresh the status and use Retry Setup when offered. Closing the Visa verification window does not cancel the allowance; return to Complete Verification when ready.

Make a CARD payment

Select the seller’s CARD charge offer and use the buyer’s InFlow API key. Omitting an instrument selection uses the account’s primary card. An explicit selection must belong to that buyer and have a usable Visa allowance. A rejected selection does not authorize switching to another card.

Provide the merchant’s business name, website, and two-letter country code. Obtain these from the seller rather than guessing from the resource URL. InFlow resolves its own Seller details when it recognizes the merchant. If the challenge requires billing information, the selected card also needs a billing postcode in Instruments.

Adapt the request, receipt checks, and cleanup in Pay with MPP using the fragments below. The examples use the primary card and an illustrative merchant; replace the merchant details with the actual seller’s information. Keep the buyer API key private.

For Go’s explicit payment flow, pass these options to the initialized buyer client’s Prepare method with the CARD challenge you selected. Wait for its credential, then submit it to the original seller. Set InstrumentID to select a particular card.

options := buyer.PaymentOptions{
    Merchant: &buyer.CardMerchant{
        Name:        "Report service",
        URL:         "https://reports.example",
        CountryCode: "US",
    },
}

In Node.js, register the CARD buyer method and provide merchant information for the request. Here, apiKey belongs to the buyer and url is the paid resource. Add instrumentId to the request context to select another card. Check the returned status and receipt; cleanup stops local work, not a completed charge.

import { card, Mppx } from '@inflowpayai/mpp-buyer';

export async function requestReport(apiKey: string, url: string) {
  const method = card({ apiKey, environment: 'sandbox' });
  const buyer = Mppx.create({
    methods: [method], polyfill: false, maxPaymentRetries: 1,
  });
  try {
    return await buyer.fetch(url, {
      context: {
        merchant: {
          name: 'Report service',
          url: 'https://reports.example',
          countryCode: 'US',
        },
      },
    });
  } finally {
    method.cleanup();
  }
}

In Python, replace the buyer-method construction in Pay with MPP with this configuration. Use it with the same payment transport and asynchronous context manager. api_key belongs to the buyer. Set instrument_id to select another card; create a separate method instance for a different merchant.

method = BuyerMethod(
    ClientOptions(api_key=api_key, environment="sandbox"),
    method="card",
    merchant={
        "name": "Report service",
        "url": "https://reports.example",
        "countryCode": "US",
    },
)

In Rust, select a card/charge challenge and use prepare_card instead of prepare. Retain the existing cancellation token, wait, credential submission, and receipt checks from Pay with MPP. Set instrument_id to Some(id) for a specific card.

use inflow_mpp_buyer::{CardPaymentOptions, Merchant};

let payment = buyer.prepare_card(
    challenge,
    CardPaymentOptions {
        merchant: Merchant {
            name: "Report service".into(),
            url: "https://reports.example".into(),
            country_code: "US".into(),
        },
        instrument_id: None,
    },
    &cancellation,
).await?;

A missing or insufficient allowance can prevent the purchase from reaching payment approval. Fix the card setup rather than waiting for an approval that was never created. Once a purchase exists, preserve its transaction reference. Do not start another purchase just because credential issuance or the seller response is taking longer than expected.

Verify payment and delivery

Complete the buyer and seller setup, then use a $1.00 USD test purchase to verify the full flow. A successfully compiled example, a 402 challenge, or a Ready allowance is not an end-to-end payment test.

  • Complete a successful purchase. Confirm the payment receipt, the settled transaction, the payment in the seller’s processor account, and delivery of the purchased result.
  • Test missing, unverified, expired, and insufficient allowances. Confirm that the buyer receives a useful failure without selecting a different card automatically.
  • Test a declined payment after credential issuance. Confirm that no paid result is delivered; do not assume the allowance capacity has been restored.
  • Interrupt a request after payment submission. Recover the existing payment’s status before deciding whether to retry delivery.
  • Replay the same credential for the same purchase. Confirm that payment is not duplicated and that your application handles repeated delivery requests safely.

If issuance has an unknown outcome, do not request another credential as an automatic retry. Use the retained transaction reference to investigate. Status and recovery explains payment-state handling; Deliver paid results covers repeated requests after payment.

Maintain the allowance

Review Available (USD), expiration, and status in VIC Allowance. Refresh the displayed details before making a decision after an interrupted request. The amount consumed from the allowance can exceed your completed purchases because credential issuance consumes capacity before payment.

Replace an allowance

Use Replace Allowance to set a new amount and expiration. Confirming the replacement stops InFlow from selecting the old allowance, even if provider cancellation fails. If creation of the replacement fails, the card may have no selected allowance. Check its status and complete verification before trying another CARD purchase.

Cancel an allowance

Cancel Allowance stops InFlow from selecting it and attempts cancellation with the provider. If that request fails, the remote allowance may remain until expiration. Cancellation does not refund payments or guarantee revocation of credentials already issued. It also does not disable the card’s separate ordinary instrument-payment capability.

Changing the primary card affects future selection; it does not replace the card on a purchase already created. Investigate outstanding purchases separately when changing cards or allowances.

Continue your integration

Approvals and allowances

Understand when owner approval is needed and how it differs from card verification.

Trusted agent verification

Treat agent identity and payment authorization as separate parts of your integration.

Test your integration

Verify successful payments, failure paths, and recovery in your application.