| name | wompi-payment-sources |
| description | Create and retrieve reusable Wompi payment sources using @pulgueta/wompi. Covers createPaymentSource (CARD or NEQUI, requires acceptance_token and privateKey), getPaymentSource, PaymentSourceStatus (AVAILABLE/PENDING), and charging a customer via payment_source_id in createTransaction. Load when building recurring billing, saved payment methods, or subscription flows.
|
| type | core |
| library | @pulgueta/wompi |
| library_version | 3.0.0 |
| requires | ["wompi-client-setup"] |
| sources | ["pulgueta/wompi-node:packages/core/src/client/payment-sources/index.ts","pulgueta/wompi-node:packages/core/src/schemas.ts"] |
This skill builds on wompi/client-setup. Read it first for key configuration and the error-first tuple pattern.
Setup
Tokenize a card, save it as a payment source, then use the source for a recurring charge.
import { WompiClient } from '@pulgueta/wompi';
import { getSignatureKey } from '@pulgueta/wompi/server';
const wompi = new WompiClient({
publicKey: process.env.WOMPI_PUBLIC_KEY!,
privateKey: process.env.WOMPI_PRIVATE_KEY!,
sandbox: process.env.NODE_ENV !== 'production',
});
const [merchantErr, merchant] = await wompi.merchants.getMerchant();
if (merchantErr) throw merchantErr;
const acceptanceToken = merchant.presigned_acceptance!.acceptance_token;
const [tokenErr, token] = await wompi.tokens.tokenizeCard({
number: '4242424242424242',
cvc: '123',
exp_month: '12',
exp_year: '29',
card_holder: 'María García',
});
if (tokenErr) throw tokenErr;
const [sourceErr, source] = await wompi.paymentSources.createPaymentSource({
type: 'CARD',
token: token.id,
acceptance_token: acceptanceToken,
customer_email: 'maria@example.com',
});
if (sourceErr) throw sourceErr;
console.log(source.id, source.status);
Core Patterns
Create a Nequi payment source
Nequi sources start as PENDING and become AVAILABLE after the customer approves in the Nequi app. Poll getPaymentSource or use webhooks to confirm availability.
const [tokenErr, nequiToken] = await wompi.tokens.tokenizeNequi({
phone_number: '3001234567',
});
if (tokenErr) throw tokenErr;
const [sourceErr, source] = await wompi.paymentSources.createPaymentSource({
type: 'NEQUI',
token: nequiToken.id,
acceptance_token: acceptanceToken,
customer_email: 'user@example.com',
});
if (sourceErr) throw sourceErr;
console.log(source.status);
Retrieve a payment source
const [error, source] = await wompi.paymentSources.getPaymentSource(sourceId);
if (error) throw error;
if (source.status === 'AVAILABLE') {
}
Charge a customer using a saved payment source
Use payment_source_id in createTransaction instead of payment_method. This requires privateKey — the transaction is authenticated with the private key, not the public key.
import { getSignatureKey } from '@pulgueta/wompi/server';
const amountInCents = 1_990_000;
const reference = `subscription-${userId}-${Date.now()}`;
const signature = await getSignatureKey({
reference,
amountInCents,
integrityKey: process.env.WOMPI_INTEGRITY_KEY!,
});
const [merchantErr, merchant] = await wompi.merchants.getMerchant();
if (merchantErr) throw merchantErr;
const acceptanceToken = merchant.presigned_acceptance!.acceptance_token;
const [error, txn] = await wompi.transactions.createTransaction({
acceptance_token: acceptanceToken,
amount_in_cents: amountInCents,
currency: 'COP',
signature,
customer_email: 'maria@example.com',
reference,
payment_source_id: source.id,
});
if (error) throw error;
console.log(txn.id, txn.status);
Common Mistakes
HIGH Calling paymentSources methods without privateKey
Wrong:
const wompi = new WompiClient({ publicKey: process.env.WOMPI_PUBLIC_KEY! });
const [error] = await wompi.paymentSources.createPaymentSource({ ... });
Correct:
const wompi = new WompiClient({
publicKey: process.env.WOMPI_PUBLIC_KEY!,
privateKey: process.env.WOMPI_PRIVATE_KEY!,
});
Both createPaymentSource and getPaymentSource require privateKey.
Source: packages/core/src/client/payment-sources/index.ts
HIGH Omitting acceptance_token when creating a payment source
Wrong:
await wompi.paymentSources.createPaymentSource({
type: 'CARD',
token: cardToken.id,
customer_email: 'user@example.com',
});
Correct:
const [merchantErr, merchant] = await wompi.merchants.getMerchant();
if (merchantErr) throw merchantErr;
const acceptanceToken = merchant.presigned_acceptance!.acceptance_token;
await wompi.paymentSources.createPaymentSource({
type: 'CARD',
token: cardToken.id,
customer_email: 'user@example.com',
acceptance_token: acceptanceToken,
});
acceptance_token is required in createPaymentSource — same merchant acceptance token used for transactions. Fetch it fresh before each call.
Source: packages/core/src/schemas.ts — CreatePaymentSourceInputSchema
MEDIUM Using payment_source_id in createTransaction without privateKey
Wrong:
const wompi = new WompiClient({ publicKey: '...' });
await wompi.transactions.createTransaction({
payment_source_id: 123,
amount_in_cents: 1_990_000,
});
Correct:
const wompi = new WompiClient({
publicKey: process.env.WOMPI_PUBLIC_KEY!,
privateKey: process.env.WOMPI_PRIVATE_KEY!,
});
Transactions using payment_source_id are authenticated with the private key. The public key is used for payment_method (inline card token) transactions only.
Source: packages/core/src/client/transactions/index.ts
HIGH Not checking the error tuple before reading data
Wrong:
const [, source] = await wompi.paymentSources.createPaymentSource(input);
await db.save({ sourceId: source.id });
Correct:
const [error, source] = await wompi.paymentSources.createPaymentSource(input);
if (error) throw error;
await db.save({ sourceId: source.id });
Source: packages/core/src/schemas.ts
See also
wompi-client-setup/SKILL.md — key types and error-tuple pattern
wompi-transactions/SKILL.md — using payment_source_id in createTransaction