This recipe is the fastest way to understand how Conomy moves money. Choose the business intent, pick the origin and destination rails, then use the generated request as the shape your backend should send to POST /payments.
Note Before showing rails in your product, call GET /payments/available-products. That response tells you which currencies, rails, node fields, and payment types are available for the identity you are operating with.
TOPUP_ACCOUNT Fund internal balance External rail as origin, internal ACCOUNT as destination. WITHDRAWAL_ACCOUNT Pay out from balance Internal ACCOUNT as origin, external rail as destination. PURCHASE Charge a customer Customer pay-in rail as origin, merchant ACCOUNT as destination. REMITTANCE Cross-border transfer Internal or pay-in origin, external payout destination. P2P Internal transfer Internal ACCOUNT to internal ACCOUNT. COLLECT Collect from accounts Multiple internal ACCOUNT origins into one ACCOUNT.
Generated request
POST /payments CLP:CLP HTTP curl JavaScript Python Go Rust
POST /sandbox/payments HTTP/1.1 : api.conomyhq.com : {YOUR_API_KEY} : Bearer {ACCESS_TOKEN} : 24-04-2025 : MyApp/1.0 : application/json : application/json { "externalId" : "topup_account-001" , "identityId" : "<IDENTITY_ID>" , "accountNumber" : "<ACCOUNT_NUMBER>" , "product" : "CLP:CLP" , "type" : "TOPUP_ACCOUNT" , "purchaseAmount" : "100000" , "purchaseCurrency" : "CLP" , "currency" : "CLP" , "origins" : [ { "type" : "ETPAY" , "currency" : "CLP" , "etpay" : { "successUrl" : "https://yourapp.com/success" , "failedUrl" : "https://yourapp.com/failed" , "customer" : { "firstName" : "Jane" , "email" : "jane@example.com" } } } ], "destinations" : [ { "type" : "ACCOUNT" , "currency" : "CLP" , "identity" : { "identityId" : "<IDENTITY_ID>" }, "account" : { "accountNumber" : "<ACCOUNT_NUMBER>" } } ] }
01 Discover products Ask Conomy which payment types, currencies, and rails are enabled for the identity.
02 Build nodes Choose one origin and one destination. Each node has a type plus its matching sub-object.
03 Create payment Send the generated payload to POST /payments from your backend.
04 Capture Capture once the customer or provider authorization is complete.
05 Reconcile Use webhooks and GET /payments/{id} to mirror final state in your system.
Use the same identity, currencies, and product context your user selected in your product. The response drives what you render in the UI.
Request HTTP curl JavaScript Python Go Rust
GET /sandbox/payments/available-products?identityId=<IDENTITY_ID>&purchaseCurrency=CLP¤cy=CLP HTTP / 1.1
Host: api.conomyhq.com
x-api-key: {YOUR_API_KEY}
Authorization: Bearer {ACCESS_TOKEN}
conomyhq-api-version: 24-04-2025
User-Agent: MyApp/1.0
Accept: application/json curl -X GET ' https://api.conomyhq.com/sandbox/payments/available-products?identityId=<IDENTITY_ID>&purchaseCurrency=CLP¤cy=CLP ' \
-H ' x-api-key: {YOUR_API_KEY} ' \
-H ' Authorization: Bearer {ACCESS_TOKEN} ' \
-H ' conomyhq-api-version: 24-04-2025 ' \
-H ' User-Agent: MyApp/1.0 ' \
-H ' Accept: application/json ' const response = await fetch ( ' https://api.conomyhq.com/sandbox/payments/available-products?identityId=<IDENTITY_ID>&purchaseCurrency=CLP¤cy=CLP ' , {
method : ' GET ' ,
headers : {
' x-api-key ' : ' {YOUR_API_KEY} ' ,
' Authorization ' : ' Bearer {ACCESS_TOKEN} ' ,
' conomyhq-api-version ' : ' 24-04-2025 ' ,
' User-Agent ' : ' MyApp/1.0 ' ,
' Accept ' : ' application/json ' ,
},
});
const data = await response . json (); import requests
response = requests . get (
' https://api.conomyhq.com/sandbox/payments/available-products?identityId=<IDENTITY_ID>&purchaseCurrency=CLP¤cy=CLP ' ,
headers ={
' x-api-key ' : ' {YOUR_API_KEY} ' ,
' Authorization ' : ' Bearer {ACCESS_TOKEN} ' ,
' conomyhq-api-version ' : ' 24-04-2025 ' ,
' User-Agent ' : ' MyApp/1.0 ' ,
' Accept ' : ' application/json ' ,
},
)
data = response . json () package main
import (
" net/http "
)
func main () {
req , _ := http . NewRequest ( " GET " , " https://api.conomyhq.com/sandbox/payments/available-products?identityId=<IDENTITY_ID>&purchaseCurrency=CLP¤cy=CLP " , nil )
req . Header . Set ( " x-api-key " , " {YOUR_API_KEY} " )
req . Header . Set ( " Authorization " , " Bearer {ACCESS_TOKEN} " )
req . Header . Set ( " conomyhq-api-version " , " 24-04-2025 " )
req . Header . Set ( " User-Agent " , " MyApp/1.0 " )
req . Header . Set ( " Accept " , " application/json " )
client := & http . Client {}
resp , _ := client . Do ( req )
defer resp . Body . Close ()
} use reqwest :: Client ;
#[ tokio :: main ]
async fn main () -> Result <(), Box < dyn std :: error :: Error >> {
let client = Client :: new ();
let response = client
. get ( " https://api.conomyhq.com/sandbox/payments/available-products?identityId=<IDENTITY_ID>&purchaseCurrency=CLP¤cy=CLP " )
. header ( " x-api-key " , " { YOUR_API_KEY } " )
. header ( " Authorization " , " Bearer { ACCESS_TOKEN } " )
. header ( " conomyhq-api-version " , " 24-04-2025 " )
. header ( " User-Agent " , " MyApp/1.0 " )
. header ( " Accept " , " application/json " )
. send ()
. await ? ;
let data : serde_json :: Value = response . json () . await ? ;
Ok (())
} {
" products " : [
{
" product " : " CLP:CLP " ,
" paymentTypes " : [
" TOPUP_ACCOUNT " ,
" WITHDRAWAL_ACCOUNT "
],
" paymentMethods " : [
" ETPAY " ,
" FINTOC " ,
" WEBPAY "
],
" withdrawalMethods " : [
" BANK_ACCOUNT "
],
" requiredFields " : {
" ETPAY " : [
" successUrl " ,
" failedUrl " ,
" customer.email "
],
" ACCOUNT " : [
" identity.identityId " ,
" account.accountNumber "
]
}
}
]
}
Use the builder above to produce the request. The important part is the node contract:
origins describes where the money starts.
destinations describes where the money should end.
type explains the business intent: top-up, withdrawal, purchase, remittance, P2P, collect, or fee.
each node has one type and one matching sub-object, such as etpay, pix, bank, or account.
For a top-up, the origin is a pay-in rail and the destination is an internal ACCOUNT.
Request HTTP curl JavaScript Python Go Rust
POST /sandbox/payments HTTP / 1.1
Host: api.conomyhq.com
x-api-key: {YOUR_API_KEY}
Authorization: Bearer {ACCESS_TOKEN}
conomyhq-api-version: 24-04-2025
User-Agent: MyApp/1.0
Content-Type: application/json
Accept: application/json
{
" externalId " : " topup-account-001 " ,
" identityId " : " <IDENTITY_ID> " ,
" accountNumber " : " <ACCOUNT_NUMBER> " ,
" product " : " CLP:CLP " ,
" type " : " TOPUP_ACCOUNT " ,
" purchaseAmount " : " 100000 " ,
" purchaseCurrency " : " CLP " ,
" currency " : " CLP " ,
" origins " : [
{
" type " : " ETPAY " ,
" currency " : " CLP " ,
" etpay " : {
" successUrl " : " https://yourapp.com/success " ,
" failedUrl " : " https://yourapp.com/failed " ,
" customer " : {
" firstName " : " Jane " ,
" email " : " jane@example.com "
}
}
}
],
" destinations " : [
{
" type " : " ACCOUNT " ,
" currency " : " CLP " ,
" identity " : {
" identityId " : " <IDENTITY_ID> "
},
" account " : {
" accountNumber " : " <ACCOUNT_NUMBER> "
}
}
]
} curl -X POST ' https://api.conomyhq.com/sandbox/payments ' \
-H ' x-api-key: {YOUR_API_KEY} ' \
-H ' Authorization: Bearer {ACCESS_TOKEN} ' \
-H ' conomyhq-api-version: 24-04-2025 ' \
-H ' User-Agent: MyApp/1.0 ' \
-H ' Content-Type: application/json ' \
-H ' Accept: application/json ' \
-d ' {
"externalId": "topup-account-001",
"identityId": "<IDENTITY_ID>",
"accountNumber": "<ACCOUNT_NUMBER>",
"product": "CLP:CLP",
"type": "TOPUP_ACCOUNT",
"purchaseAmount": "100000",
"purchaseCurrency": "CLP",
"currency": "CLP",
"origins": [
{
"type": "ETPAY",
"currency": "CLP",
"etpay": {
"successUrl": "https://yourapp.com/success",
"failedUrl": "https://yourapp.com/failed",
"customer": {
"firstName": "Jane",
"email": "jane@example.com"
}
}
}
],
"destinations": [
{
"type": "ACCOUNT",
"currency": "CLP",
"identity": {
"identityId": "<IDENTITY_ID>"
},
"account": {
"accountNumber": "<ACCOUNT_NUMBER>"
}
}
]
} ' const response = await fetch ( ' https://api.conomyhq.com/sandbox/payments ' , {
method : ' POST ' ,
headers : {
' x-api-key ' : ' {YOUR_API_KEY} ' ,
' Authorization ' : ' Bearer {ACCESS_TOKEN} ' ,
' conomyhq-api-version ' : ' 24-04-2025 ' ,
' User-Agent ' : ' MyApp/1.0 ' ,
' Content-Type ' : ' application/json ' ,
' Accept ' : ' application/json ' ,
},
body : JSON . stringify ({
" externalId " : " topup-account-001 " ,
" identityId " : " <IDENTITY_ID> " ,
" accountNumber " : " <ACCOUNT_NUMBER> " ,
" product " : " CLP:CLP " ,
" type " : " TOPUP_ACCOUNT " ,
" purchaseAmount " : " 100000 " ,
" purchaseCurrency " : " CLP " ,
" currency " : " CLP " ,
" origins " : [
{
" type " : " ETPAY " ,
" currency " : " CLP " ,
" etpay " : {
" successUrl " : " https://yourapp.com/success " ,
" failedUrl " : " https://yourapp.com/failed " ,
" customer " : {
" firstName " : " Jane " ,
" email " : " jane@example.com "
}
}
}
],
" destinations " : [
{
" type " : " ACCOUNT " ,
" currency " : " CLP " ,
" identity " : {
" identityId " : " <IDENTITY_ID> "
},
" account " : {
" accountNumber " : " <ACCOUNT_NUMBER> "
}
}
]
}),
});
const data = await response . json (); import requests
payload = {
" externalId " : " topup-account-001 " ,
" identityId " : " <IDENTITY_ID> " ,
" accountNumber " : " <ACCOUNT_NUMBER> " ,
" product " : " CLP:CLP " ,
" type " : " TOPUP_ACCOUNT " ,
" purchaseAmount " : " 100000 " ,
" purchaseCurrency " : " CLP " ,
" currency " : " CLP " ,
" origins " : [
{
" type " : " ETPAY " ,
" currency " : " CLP " ,
" etpay " : {
" successUrl " : " https://yourapp.com/success " ,
" failedUrl " : " https://yourapp.com/failed " ,
" customer " : {
" firstName " : " Jane " ,
" email " : " jane@example.com "
}
}
}
],
" destinations " : [
{
" type " : " ACCOUNT " ,
" currency " : " CLP " ,
" identity " : {
" identityId " : " <IDENTITY_ID> "
},
" account " : {
" accountNumber " : " <ACCOUNT_NUMBER> "
}
}
]
}
response = requests . post (
' https://api.conomyhq.com/sandbox/payments ' ,
headers ={
' x-api-key ' : ' {YOUR_API_KEY} ' ,
' Authorization ' : ' Bearer {ACCESS_TOKEN} ' ,
' conomyhq-api-version ' : ' 24-04-2025 ' ,
' User-Agent ' : ' MyApp/1.0 ' ,
' Content-Type ' : ' application/json ' ,
' Accept ' : ' application/json ' ,
},
json = payload ,
)
data = response . json () package main
import (
" bytes "
" net/http "
)
func main () {
payload := [] byte ( ` {
"externalId": "topup-account-001",
"identityId": "<IDENTITY_ID>",
"accountNumber": "<ACCOUNT_NUMBER>",
"product": "CLP:CLP",
"type": "TOPUP_ACCOUNT",
"purchaseAmount": "100000",
"purchaseCurrency": "CLP",
"currency": "CLP",
"origins": [
{
"type": "ETPAY",
"currency": "CLP",
"etpay": {
"successUrl": "https://yourapp.com/success",
"failedUrl": "https://yourapp.com/failed",
"customer": {
"firstName": "Jane",
"email": "jane@example.com"
}
}
}
],
"destinations": [
{
"type": "ACCOUNT",
"currency": "CLP",
"identity": {
"identityId": "<IDENTITY_ID>"
},
"account": {
"accountNumber": "<ACCOUNT_NUMBER>"
}
}
]
} ` )
body := bytes . NewReader ( payload )
req , _ := http . NewRequest ( " POST " , " https://api.conomyhq.com/sandbox/payments " , body )
req . Header . Set ( " x-api-key " , " {YOUR_API_KEY} " )
req . Header . Set ( " Authorization " , " Bearer {ACCESS_TOKEN} " )
req . Header . Set ( " conomyhq-api-version " , " 24-04-2025 " )
req . Header . Set ( " User-Agent " , " MyApp/1.0 " )
req . Header . Set ( " Content-Type " , " application/json " )
req . Header . Set ( " Accept " , " application/json " )
client := & http . Client {}
resp , _ := client . Do ( req )
defer resp . Body . Close ()
} use reqwest :: Client ;
use serde_json :: json ;
#[ tokio :: main ]
async fn main () -> Result <(), Box < dyn std :: error :: Error >> {
let client = Client :: new ();
let payload = json! ({
" externalId " : " topup-account-001 " ,
" identityId " : " <IDENTITY_ID> " ,
" accountNumber " : " <ACCOUNT_NUMBER> " ,
" product " : " CLP:CLP " ,
" type " : " TOPUP_ACCOUNT " ,
" purchaseAmount " : " 100000 " ,
" purchaseCurrency " : " CLP " ,
" currency " : " CLP " ,
" origins " : [
{
" type " : " ETPAY " ,
" currency " : " CLP " ,
" etpay " : {
" successUrl " : " https://yourapp.com/success " ,
" failedUrl " : " https://yourapp.com/failed " ,
" customer " : {
" firstName " : " Jane " ,
" email " : " jane@example.com "
}
}
}
],
" destinations " : [
{
" type " : " ACCOUNT " ,
" currency " : " CLP " ,
" identity " : {
" identityId " : " <IDENTITY_ID> "
},
" account " : {
" accountNumber " : " <ACCOUNT_NUMBER> "
}
}
]
});
let response = client
. post ( " https://api.conomyhq.com/sandbox/payments " )
. header ( " x-api-key " , " { YOUR_API_KEY } " )
. header ( " Authorization " , " Bearer { ACCESS_TOKEN } " )
. header ( " conomyhq-api-version " , " 24-04-2025 " )
. header ( " User-Agent " , " MyApp/1.0 " )
. header ( " Content-Type " , " application/json " )
. header ( " Accept " , " application/json " )
. json ( & payload )
. send ()
. await ? ;
let data : serde_json :: Value = response . json () . await ? ;
Ok (())
} {
" id " : " <PAYMENT_ID> " ,
" type " : " TOPUP_ACCOUNT " ,
" status " : " CREATED " ,
" product " : " CLP:CLP " ,
" origins " : [
{
" type " : " ETPAY " ,
" etpay " : {
" url " : " https://provider.example/authorize "
}
}
]
}
Capture when your flow is ready to commit the movement. Then mirror the final state from webhooks and from GET /payments/{id}.
Request HTTP curl JavaScript Python Go Rust
POST /sandbox/payments/{PAYMENT_ID}/captured HTTP / 1.1
Host: api.conomyhq.com
x-api-key: {YOUR_API_KEY}
Authorization: Bearer {ACCESS_TOKEN}
conomyhq-api-version: 24-04-2025
User-Agent: MyApp/1.0
Accept: application/json curl -X POST ' https://api.conomyhq.com/sandbox/payments/{PAYMENT_ID}/captured ' \
-H ' x-api-key: {YOUR_API_KEY} ' \
-H ' Authorization: Bearer {ACCESS_TOKEN} ' \
-H ' conomyhq-api-version: 24-04-2025 ' \
-H ' User-Agent: MyApp/1.0 ' \
-H ' Accept: application/json ' const response = await fetch ( ' https://api.conomyhq.com/sandbox/payments/{PAYMENT_ID}/captured ' , {
method : ' POST ' ,
headers : {
' x-api-key ' : ' {YOUR_API_KEY} ' ,
' Authorization ' : ' Bearer {ACCESS_TOKEN} ' ,
' conomyhq-api-version ' : ' 24-04-2025 ' ,
' User-Agent ' : ' MyApp/1.0 ' ,
' Accept ' : ' application/json ' ,
},
});
const data = await response . json (); import requests
response = requests . post (
' https://api.conomyhq.com/sandbox/payments/ {PAYMENT_ID} /captured ' ,
headers ={
' x-api-key ' : ' {YOUR_API_KEY} ' ,
' Authorization ' : ' Bearer {ACCESS_TOKEN} ' ,
' conomyhq-api-version ' : ' 24-04-2025 ' ,
' User-Agent ' : ' MyApp/1.0 ' ,
' Accept ' : ' application/json ' ,
},
)
data = response . json () package main
import (
" net/http "
)
func main () {
req , _ := http . NewRequest ( " POST " , " https://api.conomyhq.com/sandbox/payments/{PAYMENT_ID}/captured " , nil )
req . Header . Set ( " x-api-key " , " {YOUR_API_KEY} " )
req . Header . Set ( " Authorization " , " Bearer {ACCESS_TOKEN} " )
req . Header . Set ( " conomyhq-api-version " , " 24-04-2025 " )
req . Header . Set ( " User-Agent " , " MyApp/1.0 " )
req . Header . Set ( " Accept " , " application/json " )
client := & http . Client {}
resp , _ := client . Do ( req )
defer resp . Body . Close ()
} use reqwest :: Client ;
#[ tokio :: main ]
async fn main () -> Result <(), Box < dyn std :: error :: Error >> {
let client = Client :: new ();
let response = client
. post ( " https://api.conomyhq.com/sandbox/payments/ { PAYMENT_ID } /captured " )
. header ( " x-api-key " , " { YOUR_API_KEY } " )
. header ( " Authorization " , " Bearer { ACCESS_TOKEN } " )
. header ( " conomyhq-api-version " , " 24-04-2025 " )
. header ( " User-Agent " , " MyApp/1.0 " )
. header ( " Accept " , " application/json " )
. send ()
. await ? ;
let data : serde_json :: Value = response . json () . await ? ;
Ok (())
} {
" id " : " <PAYMENT_ID> " ,
" status " : " CAPTURED "
}
Request HTTP curl JavaScript Python Go Rust
GET /sandbox/payments/{PAYMENT_ID} HTTP / 1.1
Host: api.conomyhq.com
x-api-key: {YOUR_API_KEY}
Authorization: Bearer {ACCESS_TOKEN}
conomyhq-api-version: 24-04-2025
User-Agent: MyApp/1.0
Accept: application/json curl -X GET ' https://api.conomyhq.com/sandbox/payments/{PAYMENT_ID} ' \
-H ' x-api-key: {YOUR_API_KEY} ' \
-H ' Authorization: Bearer {ACCESS_TOKEN} ' \
-H ' conomyhq-api-version: 24-04-2025 ' \
-H ' User-Agent: MyApp/1.0 ' \
-H ' Accept: application/json ' const response = await fetch ( ' https://api.conomyhq.com/sandbox/payments/{PAYMENT_ID} ' , {
method : ' GET ' ,
headers : {
' x-api-key ' : ' {YOUR_API_KEY} ' ,
' Authorization ' : ' Bearer {ACCESS_TOKEN} ' ,
' conomyhq-api-version ' : ' 24-04-2025 ' ,
' User-Agent ' : ' MyApp/1.0 ' ,
' Accept ' : ' application/json ' ,
},
});
const data = await response . json (); import requests
response = requests . get (
' https://api.conomyhq.com/sandbox/payments/ {PAYMENT_ID} ' ,
headers ={
' x-api-key ' : ' {YOUR_API_KEY} ' ,
' Authorization ' : ' Bearer {ACCESS_TOKEN} ' ,
' conomyhq-api-version ' : ' 24-04-2025 ' ,
' User-Agent ' : ' MyApp/1.0 ' ,
' Accept ' : ' application/json ' ,
},
)
data = response . json () package main
import (
" net/http "
)
func main () {
req , _ := http . NewRequest ( " GET " , " https://api.conomyhq.com/sandbox/payments/{PAYMENT_ID} " , nil )
req . Header . Set ( " x-api-key " , " {YOUR_API_KEY} " )
req . Header . Set ( " Authorization " , " Bearer {ACCESS_TOKEN} " )
req . Header . Set ( " conomyhq-api-version " , " 24-04-2025 " )
req . Header . Set ( " User-Agent " , " MyApp/1.0 " )
req . Header . Set ( " Accept " , " application/json " )
client := & http . Client {}
resp , _ := client . Do ( req )
defer resp . Body . Close ()
} use reqwest :: Client ;
#[ tokio :: main ]
async fn main () -> Result <(), Box < dyn std :: error :: Error >> {
let client = Client :: new ();
let response = client
. get ( " https://api.conomyhq.com/sandbox/payments/ { PAYMENT_ID } " )
. header ( " x-api-key " , " { YOUR_API_KEY } " )
. header ( " Authorization " , " Bearer { ACCESS_TOKEN } " )
. header ( " conomyhq-api-version " , " 24-04-2025 " )
. header ( " User-Agent " , " MyApp/1.0 " )
. header ( " Accept " , " application/json " )
. send ()
. await ? ;
let data : serde_json :: Value = response . json () . await ? ;
Ok (())
} {
" id " : " <PAYMENT_ID> " ,
" type " : " TOPUP_ACCOUNT " ,
" status " : " SETTLED " ,
" product " : " CLP:CLP " ,
" purchaseAmount " : " 100000 " ,
" purchaseCurrency " : " CLP " ,
" currency " : " CLP "
}
Tip If your backend can complete these five steps in sandbox without manual edits, the integration path is correct: discover rails, build nodes, create payment, capture, and reconcile.