Payment Orders
Create and manage payment orders - the core transaction record in Paysera Checkout.
Payment orders represent the core transaction record in Paysera Checkout. This guide covers creating and managing orders via the API.
Overview​
A payment order contains:
- Transaction amount, currency, and your merchant reference (your order ID)
- Optional redirect URLs for success/failure/callback
- Optional
metadataandmerchant_datakey-value pairs
redirect_urls.* fields are optional in the create-order request. Provide them per environment if you need browser redirects after payment.
All amounts in the API use minor currency units (e.g., cents for EUR, pennies for GBP):
- Request: String format (e.g.,
"2500"for €25.00) - Response: Long/integer format (e.g.,
2500for €25.00)
Endpoints​
For complete request/response schemas and examples, see the Endpoint Reference:
| Method | Endpoint | Description |
|---|---|---|
| POST | /merchant-order/integration/v1/orders | Create an order |
| GET | /merchant-order/integration/v1/orders/{id} | Get a single order |
| GET | /merchant-order/integration/v1/orders | List orders |
| PATCH | /merchant-order/integration/v1/orders/{id} | Update an order before payment |
Order state is pushed to your callback_url via webhooks (recommended for real-time updates). You can also read order state directly with GET /orders/{id} and GET /orders — useful for reconciliation and on-demand lookups. See Webhooks.
Order Statuses​
| Status | Code | Description |
|---|---|---|
| Pending Payment | pending_payment | Order created, awaiting payment |
| Paid | paid | Order fully paid |
| Canceled | canceled | Order was canceled* |
| Closed | closed | Order closed, no further operations* |
*canceled and closed statuses are defined but not yet fully implemented.
See Payment Statuses Reference for complete status documentation.
Code Examples​
- PHP
- JavaScript
- Python
- Kotlin
- Go
- C#
<?php
function createPaymentOrder(string $accessToken, array $orderData): array
{
$ch = curl_init('https://api.paysera.com/merchant-order/integration/v1/orders');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . $accessToken,
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'redirect_urls' => [
'success_url' => $orderData['success_url'],
'failure_url' => $orderData['failure_url'],
'callback_url' => $orderData['callback_url'],
],
'purchase' => [
'reference' => $orderData['reference'],
'amount' => (string) $orderData['amount'], // Already in minor units
'currency' => $orderData['currency'],
],
]),
]);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($httpCode !== 201) {
throw new Exception('Failed to create order: ' . $response);
}
return json_decode($response, true);
}
// Usage - amount is in minor units (cents)
$order = createPaymentOrder($accessToken, [
'success_url' => 'https://your-site.paysera.net/success',
'failure_url' => 'https://your-site.paysera.net/failure',
'callback_url' => 'https://your-site.paysera.net/webhook',
'reference' => 'ORDER-12345',
'amount' => 2500, // €25.00 in cents
'currency' => 'EUR',
]);
echo "Order ID: " . $order['order_id'];
// Note: To get a payment URL, create a payment link using this order_id
async function createPaymentOrder(accessToken, orderData) {
const response = await fetch(
'https://api.paysera.com/merchant-order/integration/v1/orders',
{
method: 'POST',
headers: {
'Authorization': `Bearer ${accessToken}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
redirect_urls: {
success_url: orderData.successUrl,
failure_url: orderData.failureUrl,
callback_url: orderData.callbackUrl,
},
purchase: {
reference: orderData.reference,
amount: String(orderData.amount), // Already in minor units
currency: orderData.currency,
},
}),
}
);
if (!response.ok) {
throw new Error(`Failed to create order: ${await response.text()}`);
}
return response.json();
}
// Usage - amount is in minor units (cents)
const order = await createPaymentOrder(accessToken, {
successUrl: 'https://your-site.paysera.net/success',
failureUrl: 'https://your-site.paysera.net/failure',
callbackUrl: 'https://your-site.paysera.net/webhook',
reference: 'ORDER-12345',
amount: 2500, // €25.00 in cents
currency: 'EUR',
});
console.log('Order ID:', order.order_id);
// Note: To get a payment URL, create a payment link using this order_id
import requests
def create_payment_order(access_token: str, order_data: dict) -> dict:
response = requests.post(
'https://api.paysera.com/merchant-order/integration/v1/orders',
headers={
'Authorization': f'Bearer {access_token}',
'Content-Type': 'application/json',
},
json={
'redirect_urls': {
'success_url': order_data['success_url'],
'failure_url': order_data['failure_url'],
'callback_url': order_data['callback_url'],
},
'purchase': {
'reference': order_data['reference'],
'amount': str(order_data['amount']), # Already in minor units
'currency': order_data['currency'],
},
},
)
response.raise_for_status()
return response.json()
# Usage - amount is in minor units (cents)
order = create_payment_order(access_token, {
'success_url': 'https://your-site.paysera.net/success',
'failure_url': 'https://your-site.paysera.net/failure',
'callback_url': 'https://your-site.paysera.net/webhook',
'reference': 'ORDER-12345',
'amount': 2500, # €25.00 in cents
'currency': 'EUR',
})
print(f"Order ID: {order['order_id']}")
# Note: To get a payment URL, create a payment link using this order_id
import java.net.URI
import java.net.http.HttpClient
import java.net.http.HttpRequest
import java.net.http.HttpResponse
import kotlinx.serialization.json.*
suspend fun createPaymentOrder(accessToken: String, orderData: OrderData): JsonObject {
val client = HttpClient.newHttpClient()
val requestBody = buildJsonObject {
putJsonObject("redirect_urls") {
put("success_url", orderData.successUrl)
put("failure_url", orderData.failureUrl)
put("callback_url", orderData.callbackUrl)
}
putJsonObject("purchase") {
put("reference", orderData.reference)
put("amount", orderData.amount.toString()) // Already in minor units
put("currency", orderData.currency)
}
}
val request = HttpRequest.newBuilder()
.uri(URI.create("https://api.paysera.com/merchant-order/integration/v1/orders"))
.header("Authorization", "Bearer $accessToken")
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(requestBody.toString()))
.build()
val response = client.send(request, HttpResponse.BodyHandlers.ofString())
if (response.statusCode() != 201) {
throw Exception("Failed to create order: ${response.body()}")
}
return Json.parseToJsonElement(response.body()).jsonObject
}
// Usage - amount is in minor units (cents)
val order = createPaymentOrder(accessToken, OrderData(
successUrl = "https://your-site.paysera.net/success",
failureUrl = "https://your-site.paysera.net/failure",
callbackUrl = "https://your-site.paysera.net/webhook",
reference = "ORDER-12345",
amount = 2500, // €25.00 in cents
currency = "EUR"
))
println("Order ID: ${order["order_id"]}")
// Note: To get a payment URL, create a payment link using this order_id
package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
)
type OrderRequest struct {
RedirectURLs RedirectURLs `json:"redirect_urls"`
Purchase Purchase `json:"purchase"`
}
type RedirectURLs struct {
SuccessURL string `json:"success_url"`
FailureURL string `json:"failure_url"`
CallbackURL string `json:"callback_url"`
}
type Purchase struct {
Reference string `json:"reference"`
Amount string `json:"amount"`
Currency string `json:"currency"`
}
func createPaymentOrder(accessToken string, orderData OrderRequest) (map[string]interface{}, error) {
jsonData, _ := json.Marshal(orderData)
req, _ := http.NewRequest("POST",
"https://api.paysera.com/merchant-order/integration/v1/orders",
bytes.NewBuffer(jsonData))
req.Header.Set("Authorization", "Bearer "+accessToken)
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body)
if resp.StatusCode != 201 {
return nil, fmt.Errorf("failed to create order: %s", string(body))
}
var result map[string]interface{}
json.Unmarshal(body, &result)
return result, nil
}
// Usage - amount is in minor units (cents)
func main() {
order, _ := createPaymentOrder(accessToken, OrderRequest{
RedirectURLs: RedirectURLs{
SuccessURL: "https://your-site.paysera.net/success",
FailureURL: "https://your-site.paysera.net/failure",
CallbackURL: "https://your-site.paysera.net/webhook",
},
Purchase: Purchase{
Reference: "ORDER-12345",
Amount: "2500", // €25.00 in cents
Currency: "EUR",
},
})
fmt.Printf("Order ID: %s\n", order["order_id"])
// Note: To get a payment URL, create a payment link using this order_id
}
using System.Net.Http.Headers;
using System.Text;
using System.Text.Json;
public class PayseraClient
{
private readonly HttpClient _httpClient;
public PayseraClient(string accessToken)
{
_httpClient = new HttpClient();
_httpClient.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Bearer", accessToken);
}
public async Task<JsonDocument> CreatePaymentOrderAsync(OrderData orderData)
{
var request = new
{
redirect_urls = new
{
success_url = orderData.SuccessUrl,
failure_url = orderData.FailureUrl,
callback_url = orderData.CallbackUrl
},
purchase = new
{
reference = orderData.Reference,
amount = orderData.Amount.ToString(), // Already in minor units
currency = orderData.Currency
}
};
var json = JsonSerializer.Serialize(request);
var content = new StringContent(json, Encoding.UTF8, "application/json");
var response = await _httpClient.PostAsync(
"https://api.paysera.com/merchant-order/integration/v1/orders",
content);
var responseBody = await response.Content.ReadAsStringAsync();
if (!response.IsSuccessStatusCode)
{
throw new Exception($"Failed to create order: {responseBody}");
}
return JsonDocument.Parse(responseBody);
}
}
// Usage - amount is in minor units (cents)
var client = new PayseraClient(accessToken);
var order = await client.CreatePaymentOrderAsync(new OrderData
{
SuccessUrl = "https://your-site.paysera.net/success",
FailureUrl = "https://your-site.paysera.net/failure",
CallbackUrl = "https://your-site.paysera.net/webhook",
Reference = "ORDER-12345",
Amount = 2500, // €25.00 in cents
Currency = "EUR"
});
Console.WriteLine($"Order ID: {order.RootElement.GetProperty("order_id")}");
// Note: To get a payment URL, create a payment link using this order_id
Reading and Updating Orders​
You can read an order directly and update it before payment. Webhooks remain the recommended push channel for real-time status changes (see Webhooks).
Get an Order​
GET /merchant-order/integration/v1/orders/{id}
Retrieves a single order by its identifier. The order must belong to your project.
curl https://api.paysera.com/merchant-order/integration/v1/orders/{id} \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
Path Parameters​
| Parameter | Type | Required | Description |
|---|---|---|---|
id | UUID | Yes | Order identifier |
Response​
{
"id": "a6f2b8e3-5e5f-47d9-b13f-87ed2db2938a",
"project_id": "your-project-id",
"amount": 2500,
"currency": "EUR",
"status": "paid",
"reference": "ORDER-12345",
"amount_paid": 2500,
"balance_due": 0,
"callback_url": "https://example.com/webhook",
"success_url": "https://example.com/success",
"fail_url": "https://example.com/failure",
"source": "Integration",
"created_at": 1736433000,
"updated_at": 1736433600
}
Webhooks remain the recommended way to react to order changes in real time. Use this endpoint for reconciliation or on-demand lookups.
List Orders​
GET /merchant-order/integration/v1/orders
Returns a cursor-paginated list of orders for your project. Filters can be combined freely.
Query Parameters​
| Parameter | Type | Description |
|---|---|---|
status[] | string | Filter by one or more order statuses |
amount, amount_gte, amount_lte | integer | Exact / range filter on amount (minor units) |
amount_paid, amount_paid_gte, amount_paid_lte | integer | Exact / range filter on amount paid |
currency[] | string | Filter by one or more ISO 4217 currencies |
created_at_gte, created_at_lte | integer | Created-at range (Unix seconds) |
q | string | Free-text search over reference (max 255 chars) |
cursor | string | Pagination cursor |
limit | integer | Page size |
Response​
{
"items": [
{ "id": "a6f2b8e3-…", "amount": 2500, "currency": "EUR", "status": "paid" }
],
"cursor": "eyJpZCI6Li4ufQ==",
"has_more": true
}
Update an Order​
PATCH /merchant-order/integration/v1/orders/{id}
Partially updates an order before payment. At least one field must be provided.
Changing amount or currency cancels any active payment link for the order.
Returns 422 if the order is already paid or canceled.
Request​
curl -X PATCH https://api.paysera.com/merchant-order/integration/v1/orders/{id} \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "reference": "ORDER-12345-REV2", "amount": "3000", "currency": "EUR" }'
Request Parameters​
| Parameter | Type | Required | Description |
|---|---|---|---|
reference | string | No | Merchant reference (max 255 chars) |
amount | string | No | New amount in minor units, sent as a string (e.g. "3000") |
currency | string | No | New currency (ISO 4217) |
All fields optional; at least one required.
Response​
{ "order_id": "a6f2b8e3-5e5f-47d9-b13f-87ed2db2938a" }
Error Responses​
Validation Error​
{
"error": "invalid_request",
"error_description": "Validation failed",
"error_properties": {
"purchase.amount": ["Amount should be greater than 0"]
}
}
Invalid Project​
{
"error": "not_found",
"error_description": "Project not found or access denied"
}
Authentication Failure​
{
"error": "unauthorized",
"error_description": "Authentication is required to access this resource"
}
Related Documentation​
- Payment Links - Create payment links for orders
- Webhooks - Handle payment notifications
- Payment Statuses Reference - Complete status reference