curl --request POST \
--url https://api.starkfi.io/payment/execute/on-chain \
--header 'Content-Type: application/json' \
--header 'x-api-key: <api_key>' \
--data '{
"executor_id": "api_transaction",
"payment_id": "cmoejr9eh000401nyffxgmxtj",
"signed_transaction": "0x02f8b282a4ec..."
}'
const response = await fetch(
"https://api.starkfi.io/payment/execute/on-chain",
{
method: "POST",
headers: {
"Content-Type": "application/json",
"x-api-key": "<api_key>",
},
body: JSON.stringify({
executor_id: "api_transaction",
payment_id: "cmoejr9eh000401nyffxgmxtj",
signed_transaction: "0x02f8b282a4ec...",
}),
}
);
const data = await response.json();
import requests
response = requests.post(
"https://api.starkfi.io/payment/execute/on-chain",
headers={
"Content-Type": "application/json",
"x-api-key": "<api_key>",
},
json={
"executor_id": "api_transaction",
"payment_id": "cmoejr9eh000401nyffxgmxtj",
"signed_transaction": "0x02f8b282a4ec...",
},
)
data = response.json()
{
"statusCode": 200,
"success": true,
"status": "payment_confirmed",
"message": "Payment confirmed",
"data": {
"id": "cmoejr9eh000401nyffxgmxtj",
"tid_hash": "0xabc123...def456"
}
}
{
"statusCode": 200,
"success": true,
"status": "payment_received",
"message": "Payment received...waiting for worker to send transaction to blockchain.",
"data": {
"id": "cmoejr9eh000401nyffxgmxtj",
"tx_hash": "0xabc123...def456"
}
}
{
"statusCode": 409,
"success": false,
"status": "invalid_payment_status",
"message": "Order is not in a valid status for execution."
}
{
"statusCode": 400,
"success": false,
"status": "invalid_signed_transaction",
"message": "Invalid signature or mismatch with the unsigned transaction."
}
{
"statusCode": 500,
"success": false,
"status": "payment_failed",
"message": "Receipt received but transaction was reverted on-chain."
}
StarkPay
Broadcast Transactions
Submit a signed transaction to the blockchain through StarkFi’s payment infrastructure. Never broadcast directly from the user’s wallet.
POST
/
payment
/
execute
/
on-chain
curl --request POST \
--url https://api.starkfi.io/payment/execute/on-chain \
--header 'Content-Type: application/json' \
--header 'x-api-key: <api_key>' \
--data '{
"executor_id": "api_transaction",
"payment_id": "cmoejr9eh000401nyffxgmxtj",
"signed_transaction": "0x02f8b282a4ec..."
}'
const response = await fetch(
"https://api.starkfi.io/payment/execute/on-chain",
{
method: "POST",
headers: {
"Content-Type": "application/json",
"x-api-key": "<api_key>",
},
body: JSON.stringify({
executor_id: "api_transaction",
payment_id: "cmoejr9eh000401nyffxgmxtj",
signed_transaction: "0x02f8b282a4ec...",
}),
}
);
const data = await response.json();
import requests
response = requests.post(
"https://api.starkfi.io/payment/execute/on-chain",
headers={
"Content-Type": "application/json",
"x-api-key": "<api_key>",
},
json={
"executor_id": "api_transaction",
"payment_id": "cmoejr9eh000401nyffxgmxtj",
"signed_transaction": "0x02f8b282a4ec...",
},
)
data = response.json()
{
"statusCode": 200,
"success": true,
"status": "payment_confirmed",
"message": "Payment confirmed",
"data": {
"id": "cmoejr9eh000401nyffxgmxtj",
"tid_hash": "0xabc123...def456"
}
}
{
"statusCode": 200,
"success": true,
"status": "payment_received",
"message": "Payment received...waiting for worker to send transaction to blockchain.",
"data": {
"id": "cmoejr9eh000401nyffxgmxtj",
"tx_hash": "0xabc123...def456"
}
}
{
"statusCode": 409,
"success": false,
"status": "invalid_payment_status",
"message": "Order is not in a valid status for execution."
}
{
"statusCode": 400,
"success": false,
"status": "invalid_signed_transaction",
"message": "Invalid signature or mismatch with the unsigned transaction."
}
{
"statusCode": 500,
"success": false,
"status": "payment_failed",
"message": "Receipt received but transaction was reverted on-chain."
}
You must always use this endpoint for all on-chain operations. Never send transactions via your own broadcast or directly through the user’s wallet (e.g. using
sendTransaction). The user should only sign the transaction — after signing, your backend must forward it here. This ensures all required steps for payment processing and order confirmation are properly executed.string
required
Transaction executor type. Use
api_transaction when the request comes via API.string
required
Unique payment identifier generated in the Create Transaction step.
string
required
Signed transaction hex string generated by the user’s wallet after signing the
crypto_tx received from the create transaction endpoint.curl --request POST \
--url https://api.starkfi.io/payment/execute/on-chain \
--header 'Content-Type: application/json' \
--header 'x-api-key: <api_key>' \
--data '{
"executor_id": "api_transaction",
"payment_id": "cmoejr9eh000401nyffxgmxtj",
"signed_transaction": "0x02f8b282a4ec..."
}'
const response = await fetch(
"https://api.starkfi.io/payment/execute/on-chain",
{
method: "POST",
headers: {
"Content-Type": "application/json",
"x-api-key": "<api_key>",
},
body: JSON.stringify({
executor_id: "api_transaction",
payment_id: "cmoejr9eh000401nyffxgmxtj",
signed_transaction: "0x02f8b282a4ec...",
}),
}
);
const data = await response.json();
import requests
response = requests.post(
"https://api.starkfi.io/payment/execute/on-chain",
headers={
"Content-Type": "application/json",
"x-api-key": "<api_key>",
},
json={
"executor_id": "api_transaction",
"payment_id": "cmoejr9eh000401nyffxgmxtj",
"signed_transaction": "0x02f8b282a4ec...",
},
)
data = response.json()
{
"statusCode": 200,
"success": true,
"status": "payment_confirmed",
"message": "Payment confirmed",
"data": {
"id": "cmoejr9eh000401nyffxgmxtj",
"tid_hash": "0xabc123...def456"
}
}
{
"statusCode": 200,
"success": true,
"status": "payment_received",
"message": "Payment received...waiting for worker to send transaction to blockchain.",
"data": {
"id": "cmoejr9eh000401nyffxgmxtj",
"tx_hash": "0xabc123...def456"
}
}
{
"statusCode": 409,
"success": false,
"status": "invalid_payment_status",
"message": "Order is not in a valid status for execution."
}
{
"statusCode": 400,
"success": false,
"status": "invalid_signed_transaction",
"message": "Invalid signature or mismatch with the unsigned transaction."
}
{
"statusCode": 500,
"success": false,
"status": "payment_failed",
"message": "Receipt received but transaction was reverted on-chain."
}
Response
number
required
HTTP status code. Returns
200 on success.boolean
required
Whether the request succeeded.
enum<string>
required
Broadcast result status. Available options:
payment_confirmed, payment_receivedpayment_confirmed— broadcast accepted and transaction receipt confirmed on-chain. Order status updated tosuccess.payment_received— transaction confirmed on source chain. Worker (FinalizerTransferWorker) takes over to monitor the bridge via LiFi. Order status updated toreceived.
string
required
Human-readable response message.
object
required
Errors
Before broadcast
These occur during payload or order validation, before any transaction is sent to the network.| HTTP | status | When it occurs |
|---|---|---|
400 | invalid_parameters | Invalid payload — schema validation failed |
400 | invalid_chain | Order’s chain is not enabled or not supported |
404 | payment_not_found | payment_id does not exist |
409 | invalid_payment_status | Order is not in registered or retry status |
409 | missing_unsigned_transaction | Unsigned tx was not generated before execute |
400 | invalid_signed_transaction | Invalid signature or mismatch with the unsigned tx |
400 | stale_transaction_nonce | Transaction nonce is out of sync |
During broadcast
These occur after validation, during or after the broadcast to the network.| HTTP | status | When it occurs |
|---|---|---|
500 | payment_failed | Receipt received but transaction was reverted on-chain |
500 | finalizer_payment_order_on_chain_failed | Unexpected exception inside the finalizer |
500 | blockchain_transaction_failed | Exception caught by the controller before reaching the finalizer |
Order status lifecycle
Once broadcast is submitted, the order moves through the following states:registered / retry
→ processing (execute started)
→ processing (signed_tx saved)
→ success (FinalizerTransferOnChain: broadcast confirmed)
→ received (FinalizerBridgeSwapOnChain: waiting for worker)
→ success (worker completes the bridge)
→ error (any failure along the way)
Use the Check Payment Info endpoint to poll the order status after broadcasting and confirm when it reaches
success..png?fit=max&auto=format&n=I_v6ul4JDafNKFQP&q=85&s=f0ad25536f8a3ca42331fcff88ab2b26)