5-Minute Quickstart
What You’ll Build
Create a simple PAYIN order to accept a payment from a customer. This quickstart gets you up and running without diving into complex concepts.
By the end of this guide, you’ll be able to:
- Authenticate with the Koywe API
- Create a payment order
- Track the payment status
Prerequisites
Before you begin, make sure you have:
- API Key and Secret (contact soporte@koywe.com if you don’t have these)
- Organization ID
- Merchant ID
- A tool to make HTTP requests (cURL, Postman, or your preferred programming language)
This quickstart uses the sandbox environment. All payments are simulated and no real money is involved.
Fast lane: the CLI (≈ 30 seconds)
If you’re an AI agent or you just want to see an order move end-to-end, skip the HTTP walkthrough and use the Koywe CLI. Three commands — browser sign-in, pick an org, run a guided order flow:
npx @koyweforest/cli init # browser login + auto-create credentials
npx @koyweforest/cli config set organizationId <org_id>
npx @koyweforest/cli flow order # interactive: quote → create → waitflow order prompts for the type, currency, amount, and payment method, then chains quote + order creation + status polling into one command. 26 of the 142 commands (the create and update ones) accept --schema to print the full request-body JSON schema — run that before constructing a payload instead of guessing fields.
If you prefer to hit the API directly, keep reading — the rest of this page walks through the same flow with curl, Node, and Python.
Step 1: Authenticate
First, obtain an access token using your API credentials:
curl -X POST 'https://api-sandbox.koywe.com/api/v1/auth/sign-in' \
-H 'Content-Type: application/json' \
-d '{
"apiKey": "your_api_key",
"secret": "your_secret"
}'const axios = require('axios');
async function authenticate() {
const response = await axios.post(
'https://api-sandbox.koywe.com/api/v1/auth/sign-in',
{
apiKey: process.env.KOYWE_API_KEY,
secret: process.env.KOYWE_SECRET
}
);
return response.data.token;
}
// Usage
const token = await authenticate();
console.log('Token:', token);import requests
import os
def authenticate():
response = requests.post(
'https://api-sandbox.koywe.com/api/v1/auth/sign-in',
json={
'apiKey': os.environ['KOYWE_API_KEY'],
'secret': os.environ['KOYWE_SECRET']
}
)
return response.json()['token']
# Usage
token = authenticate()
print(f'Token: {token}')Response:
{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}Store this token securely. You’ll need to include it in all subsequent requests as:
Authorization: Bearer YOUR_TOKEN
The token expires after 1 hour. In production, implement token refresh logic.
Step 2: Create a Contact (Optional)
While optional, creating a contact helps you track which customer made the payment:
async function createContact(token, orgId, merchantId) {
const response = await axios.post(
`https://api-sandbox.koywe.com/api/v1/organizations/${orgId}/merchants/${merchantId}/contacts`,
{
email: 'customer@example.com',
phone: '+573001234567',
fullName: 'Juan Pérez',
countrySymbol: 'CO',
documentType: 'CC',
documentNumber: '1234567890',
businessType: 'PERSON'
},
{
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
}
}
);
return response.data;
}
// Usage
const contact = await createContact(token, 'your_org_id', 'your_merchant_id');
console.log('Contact ID:', contact.id);def create_contact(token, org_id, merchant_id):
response = requests.post(
f'https://api-sandbox.koywe.com/api/v1/organizations/{org_id}/merchants/{merchant_id}/contacts',
json={
'email': 'customer@example.com',
'phone': '+573001234567',
'fullName': 'Juan Pérez',
'countrySymbol': 'CO',
'documentType': 'CC',
'documentNumber': '1234567890',
'businessType': 'PERSON'
},
headers={
'Authorization': f'Bearer {token}',
'Content-Type': 'application/json'
}
)
return response.json()
# Usage
contact = create_contact(token, 'your_org_id', 'your_merchant_id')
print(f"Contact ID: {contact['id']}")curl -X POST 'https://api-sandbox.koywe.com/api/v1/organizations/YOUR_ORG_ID/merchants/YOUR_MERCHANT_ID/contacts' \
-H 'Authorization: Bearer YOUR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"email": "customer@example.com",
"phone": "+573001234567",
"fullName": "Juan Pérez",
"countrySymbol": "CO",
"documentType": "CC",
"documentNumber": "1234567890",
"businessType": "PERSON"
}'Step 3: Get a Quote
Get an exchange rate quote for the payment (optional but recommended for transparency):
async function getQuote(token, orgId, merchantId) {
const response = await axios.post(
`https://api-sandbox.koywe.com/api/v1/organizations/${orgId}/merchants/${merchantId}/quotes`,
{
originCurrencySymbol: 'COP',
destinationCurrencySymbol: 'COP',
amountIn: 50000, // 50,000 COP
type: 'PAYIN'
},
{
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
}
}
);
return response.data;
}
// Usage
const quote = await getQuote(token, 'your_org_id', 'your_merchant_id');
console.log('Quote:', quote);def get_quote(token, org_id, merchant_id):
response = requests.post(
f'https://api-sandbox.koywe.com/api/v1/organizations/{org_id}/merchants/{merchant_id}/quotes',
json={
'originCurrencySymbol': 'COP',
'destinationCurrencySymbol': 'COP',
'amountIn': 50000, # 50,000 COP
'type': 'PAYIN'
},
headers={
'Authorization': f'Bearer {token}',
'Content-Type': 'application/json'
}
)
return response.json()
# Usage
quote = get_quote(token, 'your_org_id', 'your_merchant_id')
print(f"Quote: {quote}")curl -X POST 'https://api-sandbox.koywe.com/api/v1/organizations/YOUR_ORG_ID/merchants/YOUR_MERCHANT_ID/quotes' \
-H 'Authorization: Bearer YOUR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"originCurrencySymbol": "COP",
"destinationCurrencySymbol": "COP",
"amountIn": 50000,
"type": "PAYIN"
}'Step 4: Create Your First PAYIN Order
Now create the payment order. This generates a payment URL where your customer can complete the payment:
async function createPayinOrder(token, orgId, merchantId, contactId) {
const response = await axios.post(
`https://api-sandbox.koywe.com/api/v1/organizations/${orgId}/merchants/${merchantId}/orders`,
{
type: 'PAYIN', // Order type: receiving payment
originCurrencySymbol: 'COP', // Currency: Colombian Pesos
destinationCurrencySymbol: 'COP', // Same currency (no conversion)
amountIn: 50000, // Amount: 50,000 COP
description: 'Payment for Order #12345', // Description for customer
externalId: `order-${Date.now()}`, // Your internal reference
contactId: contactId, // Customer who is paying
paymentMethods: [
{
method: 'PSE', // Payment method: PSE (Colombian bank transfer)
extra: { bankAccount: { name: 'BANCOLOMBIA' } } // Per-method extras
}
],
successUrl: 'https://yoursite.com/payment/success', // Redirect after success
failedUrl: 'https://yoursite.com/payment/failed' // Redirect after failure
},
{
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
}
}
);
return response.data;
}
// Usage
const order = await createPayinOrder(token, 'your_org_id', 'your_merchant_id', contact.id);
console.log('Order created:', order.id);
console.log('Payment URL:', order.paymentUrl);def create_payin_order(token, org_id, merchant_id, contact_id):
import time
response = requests.post(
f'https://api-sandbox.koywe.com/api/v1/organizations/{org_id}/merchants/{merchant_id}/orders',
json={
'type': 'PAYIN', # Order type: receiving payment
'originCurrencySymbol': 'COP', # Currency: Colombian Pesos
'destinationCurrencySymbol': 'COP', # Same currency (no conversion)
'amountIn': 50000, # Amount: 50,000 COP
'description': 'Payment for Order #12345', # Description for customer
'externalId': f'order-{int(time.time())}', # Your internal reference
'contactId': contact_id, # Customer who is paying
'paymentMethods': [
{
'method': 'PSE', # Payment method: PSE
'extra': 'BANCOLOMBIA' # Specific bank
}
],
'successUrl': 'https://yoursite.com/payment/success',
'failedUrl': 'https://yoursite.com/payment/failed'
},
headers={
'Authorization': f'Bearer {token}',
'Content-Type': 'application/json'
}
)
return response.json()
# Usage
order = create_payin_order(token, 'your_org_id', 'your_merchant_id', contact['id'])
print(f"Order created: {order['id']}")
print(f"Payment URL: {order['paymentUrl']}")curl -X POST 'https://api-sandbox.koywe.com/api/v1/organizations/YOUR_ORG_ID/merchants/YOUR_MERCHANT_ID/orders' \
-H 'Authorization: Bearer YOUR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"type": "PAYIN",
"originCurrencySymbol": "COP",
"destinationCurrencySymbol": "COP",
"amountIn": 50000,
"description": "Payment for Order #12345",
"externalId": "order-1699999999",
"contactId": "CONTACT_ID_FROM_STEP_2",
"paymentMethods": [
{
"method": "PSE",
"extra": { "bankAccount": { "name": "BANCOLOMBIA" } }
}
],
"successUrl": "https://yoursite.com/payment/success",
"failedUrl": "https://yoursite.com/payment/failed"
}'Response:
{
"id": "ord_abc123xyz",
"type": "PAYIN",
"status": "PENDING",
"amountIn": 50000,
"originCurrencySymbol": "COP",
"destinationCurrencySymbol": "COP",
"paymentUrl": "https://checkout.koywe.com/pay/ord_abc123xyz",
"externalId": "order-1699999999",
"description": "Payment for Order #12345",
"createdAt": "2025-11-13T10:00:00Z"
}Success! You’ve created your first payment order. The paymentUrl is where you should redirect your customer to complete the payment.
Step 5: Track the Order Status
You can check the order status at any time:
async function getOrderStatus(token, orgId, merchantId, orderId) {
const response = await axios.get(
`https://api-sandbox.koywe.com/api/v1/organizations/${orgId}/merchants/${merchantId}/orders/${orderId}`,
{
headers: {
'Authorization': `Bearer ${token}`
}
}
);
return response.data;
}
// Usage
const orderStatus = await getOrderStatus(token, 'your_org_id', 'your_merchant_id', order.id);
console.log('Order status:', orderStatus.status);
// Possible statuses: PENDING, PROCESSING, PAID, COMPLETED, FAILED, CANCELLED, EXPIREDdef get_order_status(token, org_id, merchant_id, order_id):
response = requests.get(
f'https://api-sandbox.koywe.com/api/v1/organizations/{org_id}/merchants/{merchant_id}/orders/{order_id}',
headers={'Authorization': f'Bearer {token}'}
)
return response.json()
# Usage
order_status = get_order_status(token, 'your_org_id', 'your_merchant_id', order['id'])
print(f"Order status: {order_status['status']}")
# Possible statuses: PENDING, PROCESSING, PAID, COMPLETED, FAILED, CANCELLED, EXPIREDcurl -X GET 'https://api-sandbox.koywe.com/api/v1/organizations/YOUR_ORG_ID/merchants/YOUR_MERCHANT_ID/orders/ORDER_ID' \
-H 'Authorization: Bearer YOUR_TOKEN'Order Status Flow:
PENDING → PROCESSING → PAID → COMPLETED- PENDING: Order created, waiting for customer payment
- PROCESSING: Payment is being processed
- PAID: Payment confirmed
- COMPLETED: Funds credited to your virtual balance
Complete End-to-End Example
Here’s a complete working example that puts it all together:
const axios = require('axios');
const BASE_URL = 'https://api-sandbox.koywe.com/api/v1';
const ORG_ID = process.env.KOYWE_ORG_ID;
const MERCHANT_ID = process.env.KOYWE_MERCHANT_ID;
const API_KEY = process.env.KOYWE_API_KEY;
const SECRET = process.env.KOYWE_SECRET;
async function main() {
try {
// 1. Authenticate
console.log('1. Authenticating...');
const authResponse = await axios.post(`${BASE_URL}/auth/sign-in`, {
apiKey: API_KEY,
secret: SECRET
});
const token = authResponse.data.token;
console.log('✓ Authenticated');
// 2. Create contact
console.log('\n2. Creating contact...');
const contactResponse = await axios.post(
`${BASE_URL}/organizations/${ORG_ID}/merchants/${MERCHANT_ID}/contacts`,
{
email: 'customer@example.com',
phone: '+573001234567',
fullName: 'Juan Pérez',
countrySymbol: 'CO',
documentType: 'CC',
documentNumber: '1234567890',
businessType: 'PERSON'
},
{ headers: { Authorization: `Bearer ${token}` } }
);
const contactId = contactResponse.data.id;
console.log('✓ Contact created:', contactId);
// 3. Create PAYIN order
console.log('\n3. Creating payment order...');
const orderResponse = await axios.post(
`${BASE_URL}/organizations/${ORG_ID}/merchants/${MERCHANT_ID}/orders`,
{
type: 'PAYIN',
originCurrencySymbol: 'COP',
destinationCurrencySymbol: 'COP',
amountIn: 50000,
description: 'Payment for Order #12345',
externalId: `order-${Date.now()}`,
contactId: contactId,
paymentMethods: [{ method: 'PSE', extra: { bankAccount: { name: 'BANCOLOMBIA' } } }],
successUrl: 'https://yoursite.com/success',
failedUrl: 'https://yoursite.com/failed'
},
{ headers: { Authorization: `Bearer ${token}` } }
);
const order = orderResponse.data;
console.log('✓ Order created:', order.id);
console.log('✓ Payment URL:', order.paymentUrl);
// 4. Check order status
console.log('\n4. Checking order status...');
const statusResponse = await axios.get(
`${BASE_URL}/organizations/${ORG_ID}/merchants/${MERCHANT_ID}/orders/${order.id}`,
{ headers: { Authorization: `Bearer ${token}` } }
);
console.log('✓ Current status:', statusResponse.data.status);
console.log('\n✅ Success! Payment order created.');
console.log('👉 Redirect your customer to:', order.paymentUrl);
} catch (error) {
console.error('❌ Error:', error.response?.data || error.message);
}
}
main();import requests
import os
import time
BASE_URL = 'https://api-sandbox.koywe.com/api/v1'
ORG_ID = os.environ['KOYWE_ORG_ID']
MERCHANT_ID = os.environ['KOYWE_MERCHANT_ID']
API_KEY = os.environ['KOYWE_API_KEY']
SECRET = os.environ['KOYWE_SECRET']
def main():
try:
# 1. Authenticate
print('1. Authenticating...')
auth_response = requests.post(
f'{BASE_URL}/auth/sign-in',
json={'apiKey': API_KEY, 'secret': SECRET}
)
auth_response.raise_for_status()
token = auth_response.json()['token']
print('✓ Authenticated')
headers = {'Authorization': f'Bearer {token}', 'Content-Type': 'application/json'}
# 2. Create contact
print('\n2. Creating contact...')
contact_response = requests.post(
f'{BASE_URL}/organizations/{ORG_ID}/merchants/{MERCHANT_ID}/contacts',
json={
'email': 'customer@example.com',
'phone': '+573001234567',
'fullName': 'Juan Pérez',
'countrySymbol': 'CO',
'documentType': 'CC',
'documentNumber': '1234567890',
'businessType': 'PERSON'
},
headers=headers
)
contact_response.raise_for_status()
contact_id = contact_response.json()['id']
print(f'✓ Contact created: {contact_id}')
# 3. Create PAYIN order
print('\n3. Creating payment order...')
order_response = requests.post(
f'{BASE_URL}/organizations/{ORG_ID}/merchants/{MERCHANT_ID}/orders',
json={
'type': 'PAYIN',
'originCurrencySymbol': 'COP',
'destinationCurrencySymbol': 'COP',
'amountIn': 50000,
'description': 'Payment for Order #12345',
'externalId': f'order-{int(time.time())}',
'contactId': contact_id,
'paymentMethods': [{'method': 'PSE', 'extra': 'BANCOLOMBIA'}],
'successUrl': 'https://yoursite.com/success',
'failedUrl': 'https://yoursite.com/failed'
},
headers=headers
)
order_response.raise_for_status()
order = order_response.json()
print(f'✓ Order created: {order["id"]}')
print(f'✓ Payment URL: {order["paymentUrl"]}')
# 4. Check order status
print('\n4. Checking order status...')
status_response = requests.get(
f'{BASE_URL}/organizations/{ORG_ID}/merchants/{MERCHANT_ID}/orders/{order["id"]}',
headers=headers
)
status_response.raise_for_status()
print(f'✓ Current status: {status_response.json()["status"]}')
print('\n✅ Success! Payment order created.')
print(f'👉 Redirect your customer to: {order["paymentUrl"]}')
except requests.exceptions.HTTPError as error:
print(f'❌ Error: {error.response.json()}')
except Exception as error:
print(f'❌ Error: {str(error)}')
if __name__ == '__main__':
main()What’s Next?
Congratulations! You’ve successfully created your first payment order. Here’s what to explore next:
Understand organizations, merchants, virtual accounts, and order types
Full production-ready integration with webhooks and error handling
Test different payment scenarios in the sandbox environment
Get real-time notifications when payments complete
Need Help?
- 📧 Email: soporte@koywe.com
- 📚 API Reference
- 🐛 Troubleshooting Guide