Use this endpoint for both internal transfers (your app paying a merchant) and external partner transfers.
Use Cases
- Internal - Your mobile app requests payment after user scans merchant QR
- External - Partner gateways with reserve accounts request transfers
Implementation
app.post('/transfer/create', verifyAuth, async (req, res) => {
const { from, to, amount, currency, memo, order } = req.body;
const callerOcid = parseInt(req.headers['x-oc-id']);
// Determine if internal or external
if (isInternalRequest(callerOcid, from)) {
return handleInternalTransfer(req, res);
} else {
return handleExternalTransfer(req, res);
}
});
async function handleInternalTransfer(req, res) {
const { from, to, amount, currency, memo, order } = req.body;
// Get user from reference
const user = await db.getUserByReference(from.reference);
if (!user) {
return res.status(400).json({
error: { code: 'ACCOUNT_NOT_FOUND', message: 'User not found' }
});
}
// Check balance
if (user.balance < parseFloat(amount)) {
return res.status(402).json({
error: { code: 'INSUFFICIENT_FUNDS', message: 'Not enough balance' }
});
}
// Process transfer
const txid = generateTxid();
await db.debitUser(user.id, amount);
// Create proof
const proof = {
txid,
issuer: YOUR_OCID,
from: { ocid: YOUR_OCID, reference: from.reference },
to: { ocid: to.ocid, reference: to.reference || order?.id },
amount,
currency,
timestamp: Math.floor(Date.now() / 1000),
memo
};
const signature = signProof(proof);
// Notify merchant
await sendMerchantWebhook(to.ocid, proof, signature);
res.json({ proof, signature });
}
Paying After Scanning Merchant QR
When your user scans a merchant’s QR code:
async function payMerchantOrder(user, merchantOrder) {
// 1. Verify the order
const merchant = await fetchMerchantMetadata(merchantOrder.ocid);
if (!verifyOrderSignature(merchantOrder.order, merchantOrder.signature, merchant.config.publicKey)) {
throw new Error('Invalid order signature');
}
// 2. Debit user
await db.debitUser(user.id, merchantOrder.order.amount);
// 3. Settle with merchant - see Settlement Guide
const proof = await settlePayment(user, merchantOrder.order, merchantOrder.ocid);
return proof;
}
Settlement Guide
Learn about the different ways to settle payments with merchants