Save a card and charge it later
Save the customer's card on their first payment, then charge it again without them present.
Every snippet runs against the sandbox: set MAMO_API_KEY to your sandbox key first.
1. Create a link that saves the card
Create a payment link with save_card set to required (or optional to let the customer choose). The customer pays it as usual, including 3D Secure where needed.
2. Get the saved card's ID
When the first payment succeeds, read payment_method.card_id from the payment.succeeded webhook or from Fetch Payment Info. Store it against your customer.
3. Charge the saved card
Call Initiate Payment with the card_id and the amount. The charge runs off-session, without 3D Secure, and returns the payment straight away.
4. Check the result
A status of captured means the money was taken. Handle failed by asking the customer to pay with a new link. See Card on file for what to tell customers when you save their card.
Full code
BASE=https://sandbox.dev.business.mamopay.com/manage_api/v1
# 1. First payment: a link that saves the card
curl -s -X POST "$BASE/links" \
-H "Authorization: Bearer $MAMO_API_KEY" \
-H "Content-Type: application/json" \
-d '{"title": "Wallet top-up", "amount": 50, "amount_currency": "AED", "save_card": "required"}'
# 2. After the customer pays, read payment_method.card_id
curl -s "$BASE/payments/$PAYMENT_ID" -H "Authorization: Bearer $MAMO_API_KEY"
# 3. Later: charge the saved card
curl -s -X POST "$BASE/payments" \
-H "Authorization: Bearer $MAMO_API_KEY" \
-H "Content-Type: application/json" \
-d '{"card_id": "'"$CARD_ID"'", "amount": 50, "external_id": "TOPUP-1042"}'const BASE = 'https://sandbox.dev.business.mamopay.com/manage_api/v1';
const headers = {
Authorization: `Bearer ${process.env.MAMO_API_KEY}`,
'Content-Type': 'application/json',
};
const mamo = (method, path, body) =>
fetch(`${BASE}${path}`, { method, headers, body: body && JSON.stringify(body) })
.then((r) => r.json());
// 1. First payment: a link that saves the card
const link = await mamo('POST', '/links', {
title: 'Wallet top-up', amount: 50, amount_currency: 'AED', save_card: 'required',
});
// 2. After the customer pays, read payment_method.card_id
const first = await mamo('GET', `/payments/${paymentId}`);
const cardId = first.payment_method.card_id;
// 3. Later: charge the saved card
const charge = await mamo('POST', '/payments', {
card_id: cardId, amount: 50, external_id: 'TOPUP-1042',
});
console.log(charge.status); // "captured" when the money was takenimport os
import requests
BASE = "https://sandbox.dev.business.mamopay.com/manage_api/v1"
HEADERS = {"Authorization": f"Bearer {os.environ['MAMO_API_KEY']}"}
# 1. First payment: a link that saves the card
link = requests.post(f"{BASE}/links", headers=HEADERS, json={
"title": "Wallet top-up", "amount": 50, "amount_currency": "AED", "save_card": "required",
}).json()
# 2. After the customer pays, read payment_method.card_id
first = requests.get(f"{BASE}/payments/{payment_id}", headers=HEADERS).json()
card_id = first["payment_method"]["card_id"]
# 3. Later: charge the saved card
charge = requests.post(f"{BASE}/payments", headers=HEADERS, json={
"card_id": card_id, "amount": 50, "external_id": "TOPUP-1042",
}).json()
print(charge["status"]) # "captured" when the money was taken<?php
const BASE = 'https://sandbox.dev.business.mamopay.com/manage_api/v1';
function mamo($method, $path, $body = null) {
$ch = curl_init(BASE . $path);
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => $method,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('MAMO_API_KEY'),
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => $body ? json_encode($body) : null,
]);
return json_decode(curl_exec($ch), true);
}
// 1. First payment: a link that saves the card
$link = mamo('POST', '/links', [
'title' => 'Wallet top-up', 'amount' => 50, 'amount_currency' => 'AED', 'save_card' => 'required',
]);
// 2. After the customer pays, read payment_method.card_id
$first = mamo('GET', "/payments/$paymentId");
$cardId = $first['payment_method']['card_id'];
// 3. Later: charge the saved card
$charge = mamo('POST', '/payments', [
'card_id' => $cardId, 'amount' => 50, 'external_id' => 'TOPUP-1042',
]);
echo $charge['status']; // "captured" when the money was takenExample response
{
"status": "captured",
"id": "PAY-E0CE93E071",
"amount": 50,
"amount_currency": "AED",
"external_id": "TOPUP-1042",
"refund_status": "No refund",
"max_refund_amount": 50,
"payment_method": {
"card_id": "CARD-5DF50209F8",
"method": "Card",
"type": "CREDIT VISA",
"card_last4": "4242",
"origin": "International card"
}
}Updated about 3 hours ago