Accepting Payments - Overview

Understanding PAYIN orders and payment acceptance

Accepting Payments (PAYIN)

Learn how to accept payments from customers using local payment methods across Latin America.

What is PAYIN?

PAYIN is the order type used to accept payments from customers into your virtual balance account.


Use Cases

E-Commerce Checkout

Accept payments for online purchases at checkout

Service Payments

Collect payments for services rendered

Subscription Billing

Recurring payments for subscriptions

Invoice Payments

Accept payments for issued invoices


How It Works

High-Level Flow

1

Customer initiates checkout

User adds items to cart and proceeds to payment

2

Your app creates PAYIN order

Send order details to Koywe API

3

Koywe returns payment URL

Receive a checkout URL for the customer

4

Customer completes payment

Customer is redirected to payment page and pays using their preferred method

5

Koywe confirms payment

Payment provider confirms and Koywe credits your virtual account

6

Your app receives webhook

You’re notified via webhook to fulfill the order

Detailed Flow Diagram


Supported Countries and Payment Methods

Colombia 🇨🇴

MethodTypeSettlement Time
PSEBank transferInstant - 2 hours
NequiMobile walletInstant

Learn more about Colombian payment methods →

Brazil 🇧🇷

MethodTypeSettlement Time
PIXInstant paymentInstant

Mexico 🇲🇽

MethodTypeSettlement Time
SPEIBank transferInstant ⚡

Chile 🇨🇱

MethodTypeSettlement Time
KhipuBank transferInstant - 2 hours

Argentina 🇦🇷

MethodTypeSettlement Time
VariousLocal methodsVaries

Prerequisites

Before integrating PAYIN orders, ensure you have:

Required:

  • ✅ API Key and Secret
  • ✅ Organization ID
  • ✅ Merchant ID
  • ✅ Understanding of Core Concepts

Recommended:

  • Webhook endpoint configured
  • Error handling implemented
  • Testing in sandbox environment

Quick Start

Want to jump right in? Follow our step-by-step integration guide:

Or try the quickstart for a faster overview:


Payment Flow Explained

Step-by-Step Process

1. Authentication

Obtain an access token using your API credentials.

1const token = await authenticate(apiKey, secret);

2. Get Available Payment Methods

Query which payment methods are available for the customer’s country.

1const methods = await getPaymentMethods('CO', 'COP');
2// Returns: PSE, NEQUI, etc.

Store customer information for tracking and compliance.

1const contact = await createContact({
2 email: 'customer@example.com',
3 fullName: 'Juan Pérez',
4 country: 'CO'
5});

4. Create PAYIN Order

Create the payment order with amount and payment method.

1const order = await createPayinOrder({
2 amount: 50000,
3 currency: 'COP',
4 paymentMethod: 'PSE',
5 contactId: contact.id
6});

5. Redirect Customer

Send customer to the payment URL to complete payment.

1window.location.href = order.paymentUrl;

6. Handle Webhooks

Listen for webhook events to know when payment is complete.

1// Webhook: order.completed
2// -> Fulfill order, send confirmation email

Order Status Progression

Understanding order statuses:

StatusDescriptionNext Action
PENDINGOrder created, waiting for customerCustomer needs to pay
PROCESSINGPayment being processedWait for confirmation
PAIDPayment confirmedFunds being settled
COMPLETEDFunds in your accountFulfill order
FAILEDPayment failedShow error to customer
EXPIREDPayment window expiredCreate new order
CANCELLEDOrder cancelledNo action needed

Key Concepts

Payment URL

Every PAYIN order returns a paymentUrl:

1{
2 "paymentUrl": "https://checkout.koywe.com/pay/ord_abc123"
3}

This URL:

  • Is hosted by Koywe
  • Provides a secure payment experience
  • Handles the payment method UI
  • Redirects back to your successUrl or failedUrl

Success and Failed URLs

Specify where to redirect customers after payment:

1{
2 "successUrl": "https://yoursite.com/payment/success",
3 "failedUrl": "https://yoursite.com/payment/failed"
4}

Best Practice: Don’t rely solely on these redirects for order fulfillment. Always use webhooks as the source of truth.

External ID (Idempotency)

Use externalId to link orders to your system and prevent duplicates:

1{
2 "externalId": "order-12345" // Your internal order ID
3}

Benefits:

  • Safe to retry failed API calls
  • Prevents duplicate charges
  • Easy reconciliation with your database

Common Integration Patterns

Pattern 1: Simple Checkout

1// 1. User clicks "Pay"
2// 2. Create order
3const order = await createPayinOrder({
4 amount: cartTotal,
5 currency: 'COP',
6 paymentMethod: 'PSE'
7});
8// 3. Redirect
9window.location.href = order.paymentUrl;
10// 4. Handle webhook
11// 5. Fulfill order

Pattern 2: Payment Method Selection

1// 1. Show available methods
2const methods = await getPaymentMethods(country, currency);
3// 2. User selects method
4// 3. Create order with selected method
5const order = await createPayinOrder({
6 amount: cartTotal,
7 currency: 'COP',
8 paymentMethod: userSelectedMethod
9});
10// 4. Redirect and handle webhook

Pattern 3: Stored Customer

1// 1. Check if customer exists
2let contact = await findContact(email);
3if (!contact) {
4 contact = await createContact(customerData);
5}
6// 2. Create order linked to contact
7const order = await createPayinOrder({
8 amount: cartTotal,
9 contactId: contact.id,
10 // ... other fields
11});
12// 3. Track payment history per contact

Next Steps


Additional Resources