Auto-Populate Card Details From a Photo

Let customers photograph their physical card to extract and tokenize the card details, then complete checkout with the returned token.

Overview

Instead of asking a customer to manually type in their card number, expiration date, and CVV, you can let them take a photo of their physical card. Coinflow extracts the card details from the image, stores them as a token in Coinflow’s PCI-compliant vault, and returns the token so you can complete the purchase.

The flow is two steps:

  1. Extract the card — send the photo to POST /tokenize/extract-card. The endpoint responds with a 307 redirect to Coinflow’s PCI-compliant vault proxy, so the card photo is processed there and never touches Coinflow’s servers. Following the redirect returns a token along with non-sensitive metadata (firstSix, lastFour, expirationMonth, expirationYear, and whether a CVV was captured).
  2. Charge the card — pass the returned token to POST /checkout/token/{merchantId} (Saved Card Checkout) to complete the purchase.

Access to POST /tokenize/extract-card requires that your company holds a PCI-DSS certification. Provide your certification to your Coinflow Integrations Representative to have the endpoint enabled for your account.

Step 1: Extract the card from the image

Send a base64-encoded photo of the card in the image field. Optionally set mimeType (defaults to image/jpeg). Authenticate with a merchant API key that has the ADMIN scope.

POST
/api/tokenize/extract-card
1curl -X POST https://api-sandbox.coinflow.cash/api/tokenize/extract-card \
2 -H "Authorization: <apiKey>" \
3 -H "Content-Type: application/json" \
4 -d '{}'

The endpoint responds with a 307 Temporary Redirect. Your HTTP client must follow the redirect and re-send the request body to the redirect location (fetch does this automatically; for curl use --location-trusted).

The response contains the token you will use for checkout, plus metadata you can use to pre-fill and confirm the card in your UI. cvvCaptured tells you whether the CVV was readable from the photo — if it is false, prompt the customer to enter their CVV manually before charging. When a CVV is captured, cvvHash contains its SHA-256 hash, so you can verify the extracted value matches the CVV your customer expects without handling the raw value.

Response
1{
2 "token": "string",
3 "firstSix": "string",
4 "lastFour": "string",
5 "expirationMonth": "string",
6 "expirationYear": "string",
7 "cvvCaptured": true,
8 "cvvHash": "string"
9}

Step 2: Charge the card with the returned token

Use the token from Step 1 as the token field of the Saved Card Checkout request. This is the same endpoint used for any saved-card (tokenized) purchase.

POST
/api/checkout/token/:merchantId
1curl -X POST https://api-sandbox.coinflow.cash/api/checkout/token/merchantId \
2 -H "x-coinflow-auth-session-key: <apiKey>" \
3 -H "Content-Type: application/json" \
4 -d '{
5 "subtotal": {
6 "cents": 1,
7 "currency": "USD"
8 },
9 "token": "string"
10}'
Response
1{
2 "paymentId": "string"
3}

Putting it together

1// 1. Extract the card from the photo
2const extractResponse = await fetch(
3 'https://api.coinflow.cash/api/tokenize/extract-card',
4 {
5 method: 'POST',
6 headers: {
7 Authorization: MERCHANT_API_KEY,
8 'Content-Type': 'application/json',
9 },
10 body: JSON.stringify({
11 image: base64CardPhoto,
12 mimeType: 'image/png',
13 }),
14 }
15);
16
17const {token, expirationMonth, expirationYear, cvvCaptured} =
18 await extractResponse.json();
19
20// 2. Charge the card using the returned token
21const checkoutResponse = await fetch(
22 `https://api.coinflow.cash/api/checkout/token/${merchantId}`,
23 {
24 method: 'POST',
25 headers: {
26 Authorization: SESSION_KEY,
27 'Content-Type': 'application/json',
28 },
29 body: JSON.stringify({
30 token,
31 subtotal: {cents: 1000},
32 // ...remaining checkout fields
33 }),
34 }
35);

If cvvCaptured is false, collect the CVV from the customer and associate it with the token before charging so the transaction can be authorized with a CVV.