Payments

Learn how to process payments, handle declines, and manage transactions with RevKeen

RevKeen processes payments through your connected payment gateway, handling tokenization, authorization, capture, and refunds. This guide covers the complete payment flow and best practices.

Supported Payment Methods

📄

Credit/Debit Cards

Visa, Mastercard, American Express, Discover, and more
📄

ACH Bank Transfer

Direct bank debits for US customers (lower fees)
📄

Saved Cards

Securely stored payment methods for returning customers

Payment Flow

RevKeen uses tokenization to ensure card data never touches your servers:

1
Tokenization

Customer enters card in secure form → token generated client-side

2
Authorization

RevKeen verifies the card can be charged for the requested amount

3
Capture

Funds are captured and transferred (usually immediate)

4
Confirmation

Customer receives receipt, subscription/invoice updated

Processing Payments via API

Create a One-Time Payment

const payment = await client.payments.create({
  customerId: 'cus_xxxxxxxx',
  amount: 9900, // $99.00 in cents
  currency: 'USD',
  paymentMethodToken: 'tok_xxxxxxxx',
  description: 'Consulting fee',
  metadata: {
    orderId: 'order_12345',
  },
});

if (payment.data.status === 'succeeded') {
  console.log('Payment successful!');
  console.log('Transaction ID:', payment.data.transactionId);
}

Pay an Invoice

// Pay an existing invoice with saved payment method
const result = await client.invoices.pay('inv_xxxxxxxx');

// Or specify a different payment method
const result = await client.invoices.pay('inv_xxxxxxxx', {
  paymentMethodId: 'pm_xxxxxxxx',
});

console.log('Invoice paid:', result.data.paidAt);

Transaction Statuses

StatusDescriptionFunds
pendingPayment initiated, awaiting processingâŗ Held
succeededPayment completed successfully✅ Captured
failedPayment declined or error occurred❌ None
requires_actionAdditional verification needed (3DS)âŗ Held
refundedFull amount returned to customerâ†Šī¸ Returned
partially_refundedPartial amount returnedâ†Šī¸ Partial

Handling Declines

When a payment fails, RevKeen provides detailed decline information:

CategoryCommon CodesRecommended Action
Insufficient Funds300, 301Ask customer to use different card or try later
Card Declined200, 204Card blocked by issuer — request new card
Invalid Card303, 530Card number invalid — re-enter card details
Expired Card202, 223Request updated card information
CVV Mismatch225Re-enter CVV — potential fraud indicator
Limit Exceeded402, 521Card limit reached — try smaller amount or different card
try {
  const payment = await client.payments.create({
    customerId: 'cus_xxxxxxxx',
    amount: 9900,
    currency: 'USD',
    paymentMethodToken: 'tok_xxxxxxxx',
  });
} catch (error) {
  if (error.code === 'payment_declined') {
    console.log('Decline code:', error.declineCode);
    console.log('Message:', error.message);
    
    // Show user-friendly message
    switch (error.declineCode) {
      case '300':
      case '301':
        return 'Insufficient funds. Please try a different card.';
      case '200':
        return 'Card declined. Please contact your bank.';
      default:
        return 'Payment failed. Please try again.';
    }
  }
}

3D Secure (3DS) Authentication

Some payments require additional verification through 3D Secure. RevKeen handles this automatically in the checkout flow:

  1. Payment initiated → Gateway determines 3DS is required
  2. Customer redirected to bank's verification page
  3. Customer completes verification (password, SMS code, etc.)
  4. Customer redirected back → Payment completes
3DS helps reduce fraud and shifts liability to the card issuer. It's required for Strong Customer Authentication (SCA) in the EU.

Processing Refunds

// Full refund
const refund = await client.refunds.create({
  transactionId: 'txn_xxxxxxxx',
});

// Partial refund
const partialRefund = await client.refunds.create({
  transactionId: 'txn_xxxxxxxx',
  amount: 2500, // Refund $25.00
});

// Refund with reason
const refund = await client.refunds.create({
  transactionId: 'txn_xxxxxxxx',
  reason: 'Customer request',
});
Refunds typically take 5-10 business days to appear on the customer's statement. You cannot refund more than the original transaction amount.

Payment Webhooks

Listen for payment events to keep your systems in sync:

EventTrigger
payment.succeededPayment completed successfully
payment.failedPayment was declined
payment.refundedRefund processed
payment.requires_actionAdditional customer action needed

Best Practices

📄

Always Use Idempotency Keys

Include an idempotency key with payment requests to prevent duplicate charges on retries.
📄

Handle Webhooks

Don't rely solely on API responses. Use webhooks for reliable payment status updates.
📄

Store Transaction IDs

Always store the transaction ID from successful payments for refunds and support inquiries.
📄

Graceful Error Handling

Show user-friendly error messages and provide clear next steps when payments fail.
Use descriptive statement descriptors so customers recognize charges on their bank statements and reduce chargebacks.

Related Resources