curl --request POST \
--url https://api.payviox.com/session \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"amount": 101,
"currency": "<string>",
"customer": "<string>",
"order_id": "<string>",
"items": [
{
"name": "Premium Plan",
"quantity": 1,
"price": 10000
}
],
"description": "<string>",
"paymentMethodId": "<string>",
"ip": "<string>",
"metadata": {
"user_id": "usr_123",
"campaign": "summer_sale"
}
}
'import requests
url = "https://api.payviox.com/session"
payload = {
"amount": 101,
"currency": "<string>",
"customer": "<string>",
"order_id": "<string>",
"items": [
{
"name": "Premium Plan",
"quantity": 1,
"price": 10000
}
],
"description": "<string>",
"paymentMethodId": "<string>",
"ip": "<string>",
"metadata": {
"user_id": "usr_123",
"campaign": "summer_sale"
}
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
amount: 101,
currency: '<string>',
customer: '<string>',
order_id: '<string>',
items: [{name: 'Premium Plan', quantity: 1, price: 10000}],
description: '<string>',
paymentMethodId: '<string>',
ip: '<string>',
metadata: {user_id: 'usr_123', campaign: 'summer_sale'}
})
};
fetch('https://api.payviox.com/session', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.payviox.com/session",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'amount' => 101,
'currency' => '<string>',
'customer' => '<string>',
'order_id' => '<string>',
'items' => [
[
'name' => 'Premium Plan',
'quantity' => 1,
'price' => 10000
]
],
'description' => '<string>',
'paymentMethodId' => '<string>',
'ip' => '<string>',
'metadata' => [
'user_id' => 'usr_123',
'campaign' => 'summer_sale'
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.payviox.com/session"
payload := strings.NewReader("{\n \"amount\": 101,\n \"currency\": \"<string>\",\n \"customer\": \"<string>\",\n \"order_id\": \"<string>\",\n \"items\": [\n {\n \"name\": \"Premium Plan\",\n \"quantity\": 1,\n \"price\": 10000\n }\n ],\n \"description\": \"<string>\",\n \"paymentMethodId\": \"<string>\",\n \"ip\": \"<string>\",\n \"metadata\": {\n \"user_id\": \"usr_123\",\n \"campaign\": \"summer_sale\"\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.payviox.com/session")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"amount\": 101,\n \"currency\": \"<string>\",\n \"customer\": \"<string>\",\n \"order_id\": \"<string>\",\n \"items\": [\n {\n \"name\": \"Premium Plan\",\n \"quantity\": 1,\n \"price\": 10000\n }\n ],\n \"description\": \"<string>\",\n \"paymentMethodId\": \"<string>\",\n \"ip\": \"<string>\",\n \"metadata\": {\n \"user_id\": \"usr_123\",\n \"campaign\": \"summer_sale\"\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.payviox.com/session")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"amount\": 101,\n \"currency\": \"<string>\",\n \"customer\": \"<string>\",\n \"order_id\": \"<string>\",\n \"items\": [\n {\n \"name\": \"Premium Plan\",\n \"quantity\": 1,\n \"price\": 10000\n }\n ],\n \"description\": \"<string>\",\n \"paymentMethodId\": \"<string>\",\n \"ip\": \"<string>\",\n \"metadata\": {\n \"user_id\": \"usr_123\",\n \"campaign\": \"summer_sale\"\n }\n}"
response = http.request(request)
puts response.read_body{
"session_id": "a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6"
}
{
"session_id": "a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6",
"redirect_url": "https://secure.zen.com/checkout/abc123xyz"
}
{
"session_id": "a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6",
"payment_error": {
"success": false,
"message": "Payment creation failed",
"error_type": "http_error"
}
}
{
"amount": [
"The amount field is required."
],
"currency": [
"The currency field is required."
]
}
{
"error": "Unauthorized"
}
{
"error": "rate_limit_exceeded",
"message": "Too many session requests",
"type": "ip",
"retry_after": 60
}
Create Session
Create a payment session with amount, currency, and items. Supports public (pk_) and secret (sk_) API keys, optional IP validation for fraud prevention, direct provider redirect via paymentMethodId, and rate limiting
curl --request POST \
--url https://api.payviox.com/session \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"amount": 101,
"currency": "<string>",
"customer": "<string>",
"order_id": "<string>",
"items": [
{
"name": "Premium Plan",
"quantity": 1,
"price": 10000
}
],
"description": "<string>",
"paymentMethodId": "<string>",
"ip": "<string>",
"metadata": {
"user_id": "usr_123",
"campaign": "summer_sale"
}
}
'import requests
url = "https://api.payviox.com/session"
payload = {
"amount": 101,
"currency": "<string>",
"customer": "<string>",
"order_id": "<string>",
"items": [
{
"name": "Premium Plan",
"quantity": 1,
"price": 10000
}
],
"description": "<string>",
"paymentMethodId": "<string>",
"ip": "<string>",
"metadata": {
"user_id": "usr_123",
"campaign": "summer_sale"
}
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
amount: 101,
currency: '<string>',
customer: '<string>',
order_id: '<string>',
items: [{name: 'Premium Plan', quantity: 1, price: 10000}],
description: '<string>',
paymentMethodId: '<string>',
ip: '<string>',
metadata: {user_id: 'usr_123', campaign: 'summer_sale'}
})
};
fetch('https://api.payviox.com/session', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.payviox.com/session",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'amount' => 101,
'currency' => '<string>',
'customer' => '<string>',
'order_id' => '<string>',
'items' => [
[
'name' => 'Premium Plan',
'quantity' => 1,
'price' => 10000
]
],
'description' => '<string>',
'paymentMethodId' => '<string>',
'ip' => '<string>',
'metadata' => [
'user_id' => 'usr_123',
'campaign' => 'summer_sale'
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.payviox.com/session"
payload := strings.NewReader("{\n \"amount\": 101,\n \"currency\": \"<string>\",\n \"customer\": \"<string>\",\n \"order_id\": \"<string>\",\n \"items\": [\n {\n \"name\": \"Premium Plan\",\n \"quantity\": 1,\n \"price\": 10000\n }\n ],\n \"description\": \"<string>\",\n \"paymentMethodId\": \"<string>\",\n \"ip\": \"<string>\",\n \"metadata\": {\n \"user_id\": \"usr_123\",\n \"campaign\": \"summer_sale\"\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.payviox.com/session")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"amount\": 101,\n \"currency\": \"<string>\",\n \"customer\": \"<string>\",\n \"order_id\": \"<string>\",\n \"items\": [\n {\n \"name\": \"Premium Plan\",\n \"quantity\": 1,\n \"price\": 10000\n }\n ],\n \"description\": \"<string>\",\n \"paymentMethodId\": \"<string>\",\n \"ip\": \"<string>\",\n \"metadata\": {\n \"user_id\": \"usr_123\",\n \"campaign\": \"summer_sale\"\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.payviox.com/session")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"amount\": 101,\n \"currency\": \"<string>\",\n \"customer\": \"<string>\",\n \"order_id\": \"<string>\",\n \"items\": [\n {\n \"name\": \"Premium Plan\",\n \"quantity\": 1,\n \"price\": 10000\n }\n ],\n \"description\": \"<string>\",\n \"paymentMethodId\": \"<string>\",\n \"ip\": \"<string>\",\n \"metadata\": {\n \"user_id\": \"usr_123\",\n \"campaign\": \"summer_sale\"\n }\n}"
response = http.request(request)
puts response.read_body{
"session_id": "a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6"
}
{
"session_id": "a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6",
"redirect_url": "https://secure.zen.com/checkout/abc123xyz"
}
{
"session_id": "a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6",
"payment_error": {
"success": false,
"message": "Payment creation failed",
"error_type": "http_error"
}
}
{
"amount": [
"The amount field is required."
],
"currency": [
"The currency field is required."
]
}
{
"error": "Unauthorized"
}
{
"error": "rate_limit_exceeded",
"message": "Too many session requests",
"type": "ip",
"retry_after": 60
}
Overview
Creates a new payment session for your customer. The session ID can be used to redirect the customer to the payment page or to fetch available payment methods.ip), return the session_id to your frontend, and let the SDK’s openSession() take the customer to the payment page. If there’s no browser in your flow, send the customer to https://secure.payviox.com/{session_id} yourself. See Choose your integration method.Authentication
This endpoint accepts both Public API Key (client-side) and Secret API Key (server-side). See Authentication for details.Authorization: Bearer YOUR_API_KEY
Integration Modes
- Client-side (SDK)
- Server-side (API)
- Client IP is automatically captured from the request
- No need to provide the
ipparameter - Ideal for: websites, single-page applications
const payviox = new Payviox('pk_live_xxxxxxxxxxxx');
await payviox.createSession({ ... });
- You can optionally provide the client’s IP address via the
ipparameter - If
ipis provided, it will be validated when the user completes payment - If
ipis not provided, no IP validation will occur - Ideal for: backend APIs, mobile app backends, server integrations
curl https://api.payviox.com/session \
-H "Authorization: Bearer sk_live_xxxxxxxxxxxx" \
-d '{ "ip": "203.0.113.42", ... }'
ip parameter, the payment page will verify that the user’s IP matches. If there’s a mismatch, the payment will be rejected with a 403 IP mismatch error.Example Requests
Client-side Example (Public API Key)
curl https://api.payviox.com/session \
-H "Authorization: Bearer pk_live_xxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-X POST \
-d '{
"amount": 10000,
"currency": "USD",
"customer": "customer_abc123",
"order_id": "order_12345",
"description": "Premium subscription",
"metadata": {"user_id": "usr_123", "plan": "premium"},
"items": [
{
"name": "Premium Plan",
"quantity": 1,
"price": 10000
}
]
}'
const response = await fetch('https://api.payviox.com/session', {
method: 'POST',
headers: {
'Authorization': 'Bearer pk_live_xxxxxxxxxxxx',
'Content-Type': 'application/json'
},
body: JSON.stringify({
amount: 10000,
currency: 'USD',
customer: 'customer_abc123',
order_id: 'order_12345',
description: 'Premium subscription',
metadata: { user_id: 'usr_123', plan: 'premium' },
items: [
{
name: 'Premium Plan',
quantity: 1,
price: 10000
}
]
})
});
const data = await response.json();
console.log(data.session_id);
import requests
url = 'https://api.payviox.com/session'
headers = {
'Authorization': 'Bearer pk_live_xxxxxxxxxxxx',
'Content-Type': 'application/json'
}
payload = {
'amount': 10000,
'currency': 'USD',
'customer': 'customer_abc123',
'order_id': 'order_12345',
'description': 'Premium subscription',
'metadata': {'user_id': 'usr_123', 'plan': 'premium'},
'items': [
{
'name': 'Premium Plan',
'quantity': 1,
'price': 10000
}
]
}
response = requests.post(url, headers=headers, json=payload)
data = response.json()
print(data['session_id'])
<?php
$apiKey = 'pk_live_xxxxxxxxxxxx';
$url = 'https://api.payviox.com/session';
$data = [
'amount' => 10000,
'currency' => 'USD',
'customer' => 'customer_abc123',
'order_id' => 'order_12345',
'description' => 'Premium subscription',
'metadata' => ['user_id' => 'usr_123', 'plan' => 'premium'],
'items' => [
[
'name' => 'Premium Plan',
'quantity' => 1,
'price' => 10000
]
]
];
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Authorization: Bearer ' . $apiKey,
'Content-Type: application/json'
]);
$response = curl_exec($ch);
curl_close($ch);
$result = json_decode($response, true);
echo $result['session_id'];
require 'net/http'
require 'json'
uri = URI('https://api.payviox.com/session')
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Post.new(uri)
request['Authorization'] = 'Bearer pk_live_xxxxxxxxxxxx'
request['Content-Type'] = 'application/json'
request.body = {
amount: 10000,
currency: 'USD',
customer: 'customer_abc123',
order_id: 'order_12345',
description: 'Premium subscription',
metadata: { user_id: 'usr_123', plan: 'premium' },
items: [
{
name: 'Premium Plan',
quantity: 1,
price: 10000
}
]
}.to_json
response = http.request(request)
result = JSON.parse(response.body)
puts result['session_id']
package main
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
)
func main() {
url := "https://api.payviox.com/session"
payload := map[string]interface{}{
"amount": 10000,
"currency": "USD",
"customer": "customer_abc123",
"order_id": "order_12345",
"description": "Premium subscription",
"metadata": map[string]string{"user_id": "usr_123", "plan": "premium"},
"items": []map[string]interface{}{
{
"name": "Premium Plan",
"quantity": 1,
"price": 10000,
},
},
}
jsonData, _ := json.Marshal(payload)
req, _ := http.NewRequest("POST", url, bytes.NewBuffer(jsonData))
req.Header.Set("Authorization", "Bearer pk_live_xxxxxxxxxxxx")
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, _ := client.Do(req)
defer resp.Body.Close()
var result map[string]interface{}
json.NewDecoder(resp.Body).Decode(&result)
fmt.Println(result["session_id"])
}
Server-side Example (Secret API Key with IP)
When creating sessions from your backend, you can provide the client’s IP address for fraud prevention:curl https://api.payviox.com/session \
-H "Authorization: Bearer sk_live_xxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-X POST \
-d '{
"amount": 10000,
"currency": "USD",
"customer": "customer_abc123",
"order_id": "order_12345",
"description": "Premium subscription",
"ip": "203.0.113.42",
"metadata": {"user_id": "usr_123", "plan": "premium"},
"items": [
{
"name": "Premium Plan",
"quantity": 1,
"price": 10000
}
]
}'
// Server-side example (Express.js)
app.post('/create-payment', async (req, res) => {
const clientIp = req.headers['x-forwarded-for'] || req.ip;
const response = await fetch('https://api.payviox.com/session', {
method: 'POST',
headers: {
'Authorization': 'Bearer sk_live_xxxxxxxxxxxx',
'Content-Type': 'application/json'
},
body: JSON.stringify({
amount: 10000,
currency: 'USD',
customer: req.body.customer,
order_id: 'order_' + Date.now(),
description: 'Premium subscription',
ip: clientIp,
metadata: { user_id: req.body.user_id, plan: 'premium' },
items: req.body.items
})
});
const data = await response.json();
res.json({ session_id: data.session_id });
});
from flask import Flask, request, jsonify
import requests
app = Flask(__name__)
@app.route('/create-payment', methods=['POST'])
def create_payment():
client_ip = request.headers.get('X-Forwarded-For', request.remote_addr)
response = requests.post(
'https://api.payviox.com/session',
headers={
'Authorization': 'Bearer sk_live_xxxxxxxxxxxx',
'Content-Type': 'application/json'
},
json={
'amount': 10000,
'currency': 'USD',
'customer': request.json['customer'],
'order_id': f'order_{int(time.time())}',
'description': 'Premium subscription',
'ip': client_ip,
'metadata': {'user_id': request.json['user_id'], 'plan': 'premium'},
'items': request.json['items']
}
)
return jsonify(response.json())
<?php
Route::post('/create-payment', function (Request $request) {
$clientIp = $request->header('X-Forwarded-For') ?? $request->ip();
$response = Http::withHeaders([
'Authorization' => 'Bearer sk_live_xxxxxxxxxxxx',
'Content-Type' => 'application/json'
])->post('https://api.payviox.com/session', [
'amount' => 10000,
'currency' => 'USD',
'customer' => $request->input('customer'),
'order_id' => 'order_' . time(),
'description' => 'Premium subscription',
'ip' => $clientIp,
'metadata' => ['user_id' => $request->input('user_id'), 'plan' => 'premium'],
'items' => $request->input('items')
]);
return response()->json($response->json());
});
ip parameter in server-side requests, no IP validation will be performed at payment time. This is useful when you can’t reliably determine the client’s IP.Direct Redirect (Skip Payment Page)
When you specify apaymentMethodId for a redirect-based payment provider (like Zen, Nicepay, PayPal, etc.), the API will automatically initiate the payment and return a redirect_url in the response.
This allows you to bypass the Payviox payment page entirely and redirect the customer directly to the payment provider.
How it works
- Create a session with a
paymentMethodIdfor a redirect-based provider - The API creates the session and initiates the payment
- You receive both
session_idandredirect_urlin the response - Redirect your customer directly to the
redirect_url
Server-side Direct Redirect Example
app.post('/checkout', async (req, res) => {
const clientIp = req.headers['x-forwarded-for'] || req.ip;
const response = await fetch('https://api.payviox.com/session', {
method: 'POST',
headers: {
'Authorization': 'Bearer sk_live_xxxxxxxxxxxx',
'Content-Type': 'application/json'
},
body: JSON.stringify({
amount: 10000,
currency: 'USD',
customer: req.body.customer,
order_id: 'order_' + Date.now(),
description: 'Premium subscription',
paymentMethodId: 'zen_card', // Redirect-based provider
ip: clientIp,
items: req.body.items
})
});
const data = await response.json();
// If redirect_url is present, redirect directly to provider
if (data.redirect_url) {
return res.redirect(data.redirect_url);
}
// Otherwise, redirect to Payviox payment page
res.redirect(`https://secure.payviox.com/${data.session_id}`);
});
Route::post('/checkout', function (Request $request) {
$clientIp = $request->header('X-Forwarded-For') ?? $request->ip();
$response = Http::withHeaders([
'Authorization' => 'Bearer sk_live_xxxxxxxxxxxx',
])->post('https://api.payviox.com/session', [
'amount' => 10000,
'currency' => 'USD',
'customer' => $request->input('customer'),
'order_id' => 'order_' . time(),
'description' => 'Premium subscription',
'paymentMethodId' => 'zen_card', // Redirect-based provider
'ip' => $clientIp,
'items' => $request->input('items')
]);
$data = $response->json();
// If redirect_url is present, redirect directly to provider
if (isset($data['redirect_url'])) {
return redirect()->away($data['redirect_url']);
}
// Otherwise, redirect to Payviox payment page
return redirect()->away('https://secure.payviox.com/' . $data['session_id']);
});
@app.route('/checkout', methods=['POST'])
def checkout():
client_ip = request.headers.get('X-Forwarded-For', request.remote_addr)
response = requests.post(
'https://api.payviox.com/session',
headers={
'Authorization': 'Bearer sk_live_xxxxxxxxxxxx',
'Content-Type': 'application/json'
},
json={
'amount': 10000,
'currency': 'USD',
'customer': request.json['customer'],
'order_id': f'order_{int(time.time())}',
'description': 'Premium subscription',
'paymentMethodId': 'zen_card', # Redirect-based provider
'ip': client_ip,
'items': request.json['items']
}
)
data = response.json()
# If redirect_url is present, redirect directly to provider
if 'redirect_url' in data:
return redirect(data['redirect_url'])
# Otherwise, redirect to Payviox payment page
return redirect(f"https://secure.payviox.com/{data['session_id']}")
Redirect-based Providers
The following providers support direct redirect:| Provider | Payment Methods |
|---|---|
| Zen | zen_card, zen_blik, etc. |
| Nicepay | nicepay_va, nicepay_ewallet, etc. |
| PayPal | paypal |
| Payssion | Various local payment methods |
| Pallapay | Crypto payments |
| Crypto.com | cryptocom |
Handling Payment Errors
If the payment initiation fails (e.g., provider API error), the response will includepayment_error along with the session_id. You can then fall back to the standard flow:
{
"session_id": "a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6",
"payment_error": {
"success": false,
"message": "Payment creation failed",
"error_type": "http_error"
}
}
payment_error is present, the session is still created. You can redirect the customer to https://secure.payviox.com/{session_id} to let them try another payment method.Example Response
{
"session_id": "a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6"
}
{
"session_id": "a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6",
"redirect_url": "https://secure.zen.com/checkout/abc123xyz"
}
{
"session_id": "a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6",
"payment_error": {
"success": false,
"message": "Payment creation failed",
"error_type": "http_error"
}
}
{
"amount": [
"The amount field is required."
],
"currency": [
"The currency field is required."
]
}
{
"error": "Unauthorized"
}
{
"error": "rate_limit_exceeded",
"message": "Too many session requests",
"type": "ip",
"retry_after": 60
}
Error Responses
400 — Validation Error
400 — Validation Error
- Required fields missing (
amount,currency,customer,order_id,items) - Amount does not match the sum of item prices
- Invalid item structure (missing name, quantity, or price)
{
"amount": ["The amount field is required."],
"currency": ["The currency field is required."]
}
400 — Payment Method Not Found
400 — Payment Method Not Found
paymentMethodId parameter references a payment method that does not exist or is not enabled for your business.How to resolve: Use the Get Payment Methods endpoint to list available methods.{
"error": "Payment method not found"
}
401 — Unauthorized
401 — Unauthorized
Authorization: Bearer header.{
"error": "Unauthorized"
}
429 — Rate Limit Exceeded
429 — Rate Limit Exceeded
retry_after field (in seconds) and a Retry-After HTTP header indicating when you can retry.How to resolve: Wait for the duration indicated by retry_after before retrying. Implement exponential backoff in your integration.{
"error": "rate_limit_exceeded",
"message": "Too many session requests",
"type": "ip",
"retry_after": 60
}
ip parameter when creating the session, the payment page will verify that the user’s IP matches. This is a fraud prevention measure.Next Steps
After creating a session:Open the session with the SDK
openSession() in the browserRedirect without the SDK
https://secure.payviox.com/{session_id} yourselfGet Payment Methods
Dashboard
API Playground
Validation Rules
Amount Validation
Amount Validation
- Minimum amount: 100 cents ($1.00)
- Must be a positive integer
- Total amount must equal the sum of all items (price × quantity)
Items Validation
Items Validation
- At least one item is required
- Each item must have a name, quantity, and price
- Quantity must be at least 1
- Price must be at least 1 cent
Order ID
Order ID
- Must be unique per business
- Used for tracking and webhooks
- Recommended to use your internal order/transaction ID
Authorizations
Bearer authentication header of the form Bearer <token>, where <token> is your auth token.
Body
Payment amount in cents (e.g., 10000 = $100.00)
x >= 100Three-letter ISO currency code (e.g., USD)
3Customer identifier (email, customer ID, or unique identifier)
Your unique order identifier
Array of items being purchased
[
{
"name": "Premium Plan",
"quantity": 1,
"price": 10000
}
]
Optional description of the payment
Force a specific payment method (optional)
Server-side only. The end-user's IP address
Custom key-value pairs to attach to this session. These will be returned in webhook notifications.
{
"user_id": "usr_123",
"campaign": "summer_sale"
}
Response
Session created successfully
Unique identifier for the created session