RevKeenDocs

Payments and Refunds

Process payments, issue refunds, manage credit notes, and handle multi-gateway reversals

RevKeen processes payments through your connected payment gateway, handling tokenization, authorization, capture, and refunds. This guide covers the complete payment flow, refund processing, credit notes, 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 (email verification + CVV required)

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 processingHeld
succeededPayment completed successfullyCaptured
failedPayment declined or error occurredNone
requires_actionAdditional verification needed (3DS)Held
refundedFull amount returned to customerReturned
partially_refundedPartial amount returnedPartial
voidedReversed before settlementReleased

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);

    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.

Reversing Payments: Void vs Refund

RevKeen provides intelligent payment reversal options based on settlement timing. Understanding when to use each method can save you significant processing fees.

How It Works

MethodTimingProcessing FeesCustomer Impact
VoidBefore daily settlement (typically before 8 PM ET)No feesCharge never appears on statement
RefundAfter daily settlementOriginal fees not returnedShows as separate refund transaction

Settlement Timing and Smart Warnings

RevKeen automatically tracks settlement timing for each payment gateway and provides real-time warnings to help you choose the best reversal method.

Safe to Void -- Settlement is 2+ hours away. Void will succeed with high confidence. This is the recommended option to avoid processing fees.

High-Risk Void Window -- Settlement is within 15 minutes. The batch may have already closed. If void fails, you will need to process a refund instead. The dashboard will show "Attempt Void" with a warning alert.

Settlement Complete -- Transaction has been settled. Void is no longer available. You must process a refund to return funds to the customer.

Smart Reversal Logic: RevKeen automatically determines eligibility based on your gateway's settlement schedule. When you view a payment, you'll see only the available options with clear warnings for high-risk scenarios.

Using the Dashboard

  1. Navigate to Invoice or Payment -- Go to Invoices, select invoice, click payment row actions menu.
  2. Choose Reversal Method -- The dialog will show available options based on settlement status. Review settlement timing information and any warnings displayed.
  3. Confirm and Execute -- Click the action button ("Void Payment", "Attempt Void", or "Process Refund") to execute the reversal.

Important: If a high-risk void fails because settlement already occurred, you will need to manually process a refund. The system cannot automatically fall back to refund due to accounting and tax implications.

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.

Credit Notes

Credit notes are RevKeen's single reversal document. Instead of separate void, refund, and credit workflows, merchants issue credit notes against a paid invoice and RevKeen automatically routes the correct gateway operation (void, refund, terminal reversal, bank payout) based on the original payment's gateway, payment method, and context.

A credit note is always issued against a specific invoice -- it is the formal accounting record that reduces or reverses the amount owed on that invoice.

When to Use Credit Notes

  • Invoice Corrections -- Wrong amount charged, billing error, or service not delivered as promised.
  • Service Credits -- Goodwill credits, promotional adjustments, or compensation for service issues.
  • Subscription Cancellations -- Prorate refunds when canceling subscriptions mid-period.
  • Partial Refunds -- Return a portion of the invoice amount while keeping the invoice active.
  • Voiding Unpaid Invoices -- A full credit note on an unpaid invoice automatically voids it.

Creating Credit Notes from the Dashboard

There are two ways to issue a credit note:

From an Invoice (most common):

  1. Go to Invoices and open a paid invoice.
  2. Click Issue Credit Note in the invoice actions.
  3. Choose full or partial amount, select a reason, and pick a credit method.

From the Customer page:

  1. Go to Customers and open a customer.
  2. Switch to the Credit Notes tab.
  3. Click Issue Credit Note -- this shows a list of the customer's paid invoices.
  4. Select the invoice you want to credit.
  5. Fill in the credit note details (amount, reason, credit method).

The Credit Notes tab also displays all existing credit notes for that customer with their current status (Processing, Refunded, Failed).

Credit Note Options

Credit MethodEffectBest For
Refund to Payment MethodIssues credit note and automatically processes the correct gateway reversalCustomer paid and wants money back
Customer BalanceIssues credit note and adds credit to customer accountCustomer wants credit toward future purchases
Credit Note OnlyIssues credit note for record-keeping onlyManual refund outside RevKeen or goodwill gesture

Automatic Gateway Routing

When you select "Refund to Payment Method", you do not choose which gateway to use. RevKeen automatically determines the correct reversal operation based on how the original payment was made. The routing is fully automatic -- the system reads the payment's gateway from the transaction record and selects the best operation.

Original Payment MethodWhat RevKeen Does Automatically
Card (online via NMI)Void (if pre-settlement) or refund (if post-settlement)
Card (terminal / PAX)Terminal reversal (same-day), terminal refund (card re-present), or NMI gateway-direct fallback if terminal is offline
Bank transfer (fire.com)Cancel (if pending) or credit transfer payout to customer IBAN (if settled)
Customer balanceInstant ledger reversal (no gateway call needed)

For terminal payments, RevKeen checks whether the terminal is reachable and whether the customer is present before choosing between a terminal-native reversal and a gateway-direct fallback. If the terminal is offline, the refund is processed through the payment processor without requiring the terminal.

You don't pick NMI vs Terminal vs Bank. RevKeen knows how the customer originally paid and routes accordingly. For invoices paid with multiple payments across different gateways, each payment is reversed through its own original gateway.

Multi-Payment Invoices (LIFO Allocation)

When an invoice was paid with multiple payments (for example, a partial card payment and a balance payment), RevKeen allocates the credit in last-in, first-out (LIFO) order. The most recent payment is reversed first, then the next most recent, until the full credit amount is allocated. Each payment is reversed through its own original gateway.

Multiple Credit Notes per Invoice

You can issue multiple credit notes against the same invoice. RevKeen validates that the total credited amount never exceeds the invoice total. When credit notes sum to the full invoice amount, the invoice is automatically marked as voided.

Intelligent Tax Handling

RevKeen automatically calculates proportional tax adjustments when issuing credit notes:

  • Proportional Tax Credits -- Tax amounts are automatically calculated proportionally to the credited amount. For example, crediting 50% of an invoice also credits 50% of the tax.
  • Penny-Perfect Chain Handling -- When issuing multiple credit notes against the same invoice, the final credit note automatically "sweeps" any remaining fractional pennies of tax. This prevents 1-2 cent discrepancies that can occur with rounding in credit note chains.
  • Tax Provider Sync -- Credit notes automatically sync with your tax provider (Quaderno, TaxJar, etc.) to maintain accurate tax records and compliance reports.

Subscription Cancellation Protection

When issuing a credit note with subscription cancellation, RevKeen implements a safety guard: if you select "Refund to Payment Method" with subscription cancellation, the subscription will only cancel if the refund succeeds. This prevents scenarios where a customer loses access but didn't receive their refund due to gateway errors or expired payment methods.

If the refund fails, a warning is logged and the subscription remains active. You can then manually process the refund and cancel separately.

Notifications

When a credit note is issued, the following notifications are sent automatically:

  • Merchant notification -- An in-app notification appears in the dashboard bell icon confirming the credit note was issued, including the amount and customer name.
  • Customer notification -- An event is dispatched to the notifications service, which can deliver via email, SMS, or WhatsApp depending on your notification channel configuration in Settings > Notifications.

Note: Credit note email receipts and delivery channel selection (email, SMS, WhatsApp) per credit note are on the roadmap. Currently, customer notifications follow your global notification preferences.

Creating Credit Notes via API

// Issue credit note with automatic refund (gateway auto-routed)
const creditNote = await client.creditNotes.create({
  invoiceId: 'inv_xxxxxxxx',
  amount: 5000, // $50.00 in cents
  reason: 'Service not delivered',
  creditMethod: 'refund_to_payment_method',
  cancelSubscription: true,
});

// Issue credit note with customer balance
const creditNote = await client.creditNotes.create({
  invoiceId: 'inv_xxxxxxxx',
  amount: 5000,
  reason: 'Goodwill credit',
  creditMethod: 'customer_balance',
});

// Credit note only (no financial movement)
const creditNote = await client.creditNotes.create({
  invoiceId: 'inv_xxxxxxxx',
  amount: 5000,
  reason: 'Manual adjustment',
  creditMethod: 'none',
});

V2 API: Auto-Routing

When using the V2 API, pass auto_route: true to trigger multi-gateway reversal routing. For terminal (card-present) transactions, you can also specify customer_present to indicate whether the customer is physically at the terminal:

// V2 API with auto-routing
const response = await fetch('/v2/credit_notes', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer sk_live_xxxxxxxx',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    invoice_id: 'inv_xxxxxxxx',
    amount_minor: 5000,
    credit_method: 'refund_to_payment_method',
    reason: 'Service not delivered',
    auto_route: true,         // Enable multi-gateway routing
    customer_present: false,   // Terminal: is customer at the device?
  }),
});

Audit Trail: All credit notes include reason codes, creator information, timestamp, gateway operation details, and links to associated refunds/voids. They appear on customer statements and integrate with your accounting system for complete financial reconciliation.

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.capturedAuthorized payment captured
payment.disputedChargeback received
payment.requires_actionAdditional customer action needed
void.succeededPre-settlement void completed
void.failedVoid failed (transaction already settled)
credit_note.createdCredit note issued against invoice
credit_note.appliedCredit note reversal completed (refund/void processed)
credit_note.voidedCredit note canceled or voided

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.
  • Descriptive Statement Descriptors -- Use descriptive statement descriptors so customers recognize charges on their bank statements and reduce chargebacks.