İçeriğe atlayın

API

Bu sayfada

Oluştur

Kripto ödeme almak için fatura oluşturun. İki akış: doğrudan kripto (token ve ağ sabit) ve fiat (müşteri token'ı hosted checkout'ta seçer).

POST/v1/invoices

API anahtarı: Payment

İstek gövdesi

Parametre Tip Zorunlu Açıklama
project_id string Evet Önekli proje kimliği (prj_...). API anahtarı satıcı kapsamlıdır; faturanın hangi projeye açılacağını belirtin
amount string Evet Ondalık dize olarak ödeme tutarı (ör. "50.00")
currency string Evet Fiat para birimi kodu (USD, EUR vb.) veya kripto varlık sembolü. Tam liste için bkz. Desteklenen Para Birimleri
network string Koşullu Blockchain ağ kodu — TRC20, ERC20, BEP20, POLYGON, ARBITRUM, OPTIMISM, BASE, TON, AVAX, SOL, NEAR, SUI veya PLASMA (bkz. Desteklenen Para Birimleri). Kripto faturayı belirli bir ağa sabitlemek istediğinizde zorunludur
external_order_id string Evet Benzersiz sipariş kimliğiniz (en fazla 128 karakter), proje başına benzersizdir. Fatura oluşturmayı idempotent yapar: projede bu external_order_id ile bir fatura zaten varsa, mevcut fatura 200 OK ile döner — kopya değil, hata değil
client_id string Hayır Müşteri kimliğiniz (en fazla 200 karakter). Faturada saklanır; okuma yanıtlarında ve liste kayıtlarında geri döner, böylece faturaları kendi müşterinize göre gruplayabilirsiniz. Paymos bu alana dayalı bir sınır uygulamaz
allow_multiple_payments boolean Hayır Faturanın birden fazla kısmi ödeme kabul edip etmediği. Varsayılan: true
customer_fee_percent integer Hayır Müşteriye yansıtılan komisyon yüzdesi (0-100). Bu fatura için proje düzeyindeki ayarı geçersiz kılar

Fiat tutar hassasiyeti

Fiat akışlı faturalarda amount, currency biriminin küçük birimine uymalıdır.

Küçük birim Para birimleri
0 ondalık JPY, KRW, VND, CLP
2 ondalık USD, EUR, GBP, CHF, CAD, AUD, NZD, PLN, CZK, DKK, SEK, NOK, HUF, RUB, UAH, GEL, CNY, HKD, INR, IDR, MYR, PHP, THB, PKR, SGD, BRL, MXN, ARS, TRY, AED, ILS, NGN, ZAR, BDT, BMD, LKR, MMK, SAR, TWD, VEF
3 ondalık BHD, KWD

Örnekler: 23.34 USD için geçerlidir; 23.345 USD için reddedilir; 23 JPY için geçerlidir; 23.01 JPY için reddedilir.

Akış belirleme

Akış, hangi alanları sağladığınıza göre belirlenir. currency, tutarın bir token'da mı yoksa fiat'ta mı fiyatlandığını; network, zincirin baştan sabit mi yoksa müşteri tarafından mı seçileceğini belirler.

currency network Akış Müşterinin hâlâ seçtiği
token (USDT, USDC, …) bir ağ (TRC20, ERC20, …) Doğrudan kriptoamount, sabit bir zincirde token tutarıdır Hiçbir şey — token ve ağ kilitli
token (USDT, USDC, …) Kripto akışıamount token tutarıdır, zincir açık Ödenecek ağ
fiat (USD, EUR, …) Fiat akışıamount bir fiat tutarıdır Token ve ağ

Her fatura awaiting_client durumunda oluşturulur — henüz ödeme adresi yoktur. Adresi atayan ve faturayı awaiting_payment durumuna taşıyan, müşterinin hosted checkout'taki seçimidir. Doğrudan kripto durumunda seçilecek bir şey kalmadığı için checkout, önceden ayarlanmış token ve ağı onaylar ve adresi tek adımda atar. Fiat akışında, fiat-kripto kuru o anda kilitlenir ve payment.exchange_rate olarak döndürülür.

Tam yaşam döngüsü, başlangıç durumları ve kur kilitleme anlambilimi için Ödeme akışı → İki oluşturma akışı bölümüne bakın.

Örnek istek — fiat akışı

Tutar fiat cinsindendir; müşteri hosted sayfada bir token seçer ve kur seçim anında kilitlenir.

{
  "project_id": "prj_xFukZuAJZR06pLVBh3uwzv",
  "amount": "50.00",
  "currency": "USD",
  "external_order_id": "order-12345",
  "client_id": "customer-67890"
}

Örnek istek — doğrudan kripto

Token + ağ, oluşturma anında sabittir; bir adres hemen atanır.

{
  "project_id": "prj_xFukZuAJZR06pLVBh3uwzv",
  "amount": "50.00",
  "currency": "USDT",
  "network": "TRC20",
  "external_order_id": "order-12345",
  "client_id": "customer-67890"
}

Kod örnekleri

Her sekme, o dilin resmî SDK'sını kullanır. İmzalama, serileştirme, güvenli yeniden denemeler ve tiplenmiş hatalar SDK tarafından yönetilir.

API_KEY_ID="pk_live_xxxxxxxxxxxx"
API_SECRET="sk_live_xxxxxxxxxxxx"
BODY='{"project_id":"prj_xxxxxxxxxxxx","amount":"100.00","currency":"USD","external_order_id":"order-123","client_id":"customer-456"}'

TS=$(date +%s)
BODY_HASH=$(printf '%s' "$BODY" | openssl dgst -sha256 -hex | sed 's/^.* //')
SIGNATURE=$(printf '%s\n%s\n%s\n%s\n%s' "$TS" POST /v1/invoices '' "$BODY_HASH" \
  | openssl dgst -sha256 -hmac "$API_SECRET" -binary | base64)

curl -sS https://api.paymos.io/v1/invoices \
  -H "Authorization: HMAC-SHA256 $API_KEY_ID:$SIGNATURE" \
  -H "X-Request-Timestamp: $TS" \
  -H "Content-Type: application/json" \
  -d "$BODY"
import { Paymos, externalOrderId } from '@paymos/sdk';

const paymos = new Paymos({
  apiKey: process.env.PAYMOS_API_KEY,
  apiSecret: process.env.PAYMOS_API_SECRET,
});

const invoice = await paymos.invoices.create({
  projectId: 'prj_xxxxxxxxxxxx',
  amount: '100.00',
  currency: 'USD',
  externalOrderId: externalOrderId('order'),
  clientId: 'customer-456',
});

console.log(invoice.invoiceId, invoice.paymentUrl);
import os

from paymos import Paymos

paymos = Paymos(
    api_key=os.environ["PAYMOS_API_KEY"],
    api_secret=os.environ["PAYMOS_API_SECRET"],
)
invoice = paymos.invoices.create(
    project_id="prj_xxxxxxxxxxxx",
    amount="100.00",
    currency="USD",
    external_order_id="order-123",
    client_id="customer-456",
)

print(invoice["invoice_id"], invoice["payment_url"])
<?php
use Paymos\Client;
use Paymos\ClientConfig;
use Paymos\IdempotencyKey;

$paymos = new Client(new ClientConfig(
    getenv('PAYMOS_API_KEY'),
    getenv('PAYMOS_API_SECRET')
));
$invoice = $paymos->invoices()->create(array(
    'project_id' => 'prj_xxxxxxxxxxxx',
    'amount' => '100.00',
    'currency' => 'USD',
    'external_order_id' => IdempotencyKey::externalOrderId('order'),
    'client_id' => 'customer-456',
));

echo $invoice['invoice_id'] . ' ' . $invoice['payment_url'];
package main

import (
	"context"
	"fmt"
	"os"

	paymos "github.com/Paymos-labs/go-sdk/v2"
)

func main() {
	client, err := paymos.NewClient(os.Getenv("PAYMOS_API_KEY"), os.Getenv("PAYMOS_API_SECRET"))
	if err != nil {
		panic(err)
	}
	invoice, err := client.Invoices.Create(context.Background(), paymos.CreateInvoiceParams{
		ProjectID:       "prj_xxxxxxxxxxxx",
		Amount:          "100.00",
		Currency:        "USD",
		ExternalOrderID: "order-123",
		ClientID:        stringPointer("customer-456"),
	})
	if err != nil {
		panic(err)
	}
	fmt.Println(invoice.InvoiceID, invoice.PaymentURL)
}

func stringPointer(value string) *string { return &value }
using Paymos;

using var paymos = new PaymosClient(
    Environment.GetEnvironmentVariable("PAYMOS_API_KEY")!,
    Environment.GetEnvironmentVariable("PAYMOS_API_SECRET")!);

var invoice = await paymos.Invoices.CreateAsync(new CreateInvoiceRequest(
    ProjectId: "prj_xxxxxxxxxxxx",
    Amount: "100.00",
    Currency: "USD",
    ExternalOrderId: "order-123",
    ClientId: "customer-456"));

Console.WriteLine($"{invoice.InvoiceId} {invoice.PaymentUrl}");
import io.paymos.CreateInvoiceRequest;
import io.paymos.Invoice;
import io.paymos.PaymosClient;

PaymosClient paymos = new PaymosClient(
    System.getenv("PAYMOS_API_KEY"),
    System.getenv("PAYMOS_API_SECRET"));

Invoice invoice = paymos.invoices.create(
    CreateInvoiceRequest.builder()
        .projectId("prj_xxxxxxxxxxxx")
        .amount("100.00")
        .currency("USD")
        .externalOrderId("order-123")
        .clientId("customer-456")
        .build());

System.out.println(invoice.invoiceId() + " " + invoice.paymentUrl());
require 'paymos'

paymos = Paymos::Client.new(
  api_key: ENV.fetch('PAYMOS_API_KEY'),
  api_secret: ENV.fetch('PAYMOS_API_SECRET')
)
invoice = paymos.invoices.create(
  project_id: 'prj_xxxxxxxxxxxx',
  amount: '100.00',
  currency: 'USD',
  external_order_id: 'order-123',
  client_id: 'customer-456'
)

puts "#{invoice.invoice_id} #{invoice.payment_url}"
use paymos::{CreateInvoiceRequest, PaymosClient};

let paymos = PaymosClient::new(
    std::env::var("PAYMOS_API_KEY")?,
    std::env::var("PAYMOS_API_SECRET")?,
)?;
let invoice = paymos
    .invoices()
    .create(&CreateInvoiceRequest {
        project_id: "prj_xxxxxxxxxxxx".to_owned(),
        amount: "100.00".to_owned(),
        currency: "USD".to_owned(),
        external_order_id: "order-123".to_owned(),
        network: None,
        allow_multiple_payments: None,
        customer_fee_percent: None,
        client_id: Some("customer-456".to_owned()),
    })
    .await?;

println!("{} {}", invoice.invoice_id, invoice.payment_url);

Yanıt (201 Created / idempotent eşleşmede 200)

{
  "invoice_id": "inv_5CcyDYmMUGtzYL10q0Iimr",
  "project_id": "prj_xFukZuAJZR06pLVBh3uwzv",
  "status": "awaiting_client",
  "is_final": false,
  "is_test": true,
  "payment_url": "https://checkout.paymos.io/invoice/inv_5CcyDYmMUGtzYL10q0Iimr",
  "order": {
    "external_id": "order-12345",
    "client_id": "customer-67890",
    "amount": "50.00",
    "currency": "USD"
  },
  "created_at": 1743594000,
  "updated_at": 1743594000,
  "expires_at": 1743597600
}

Yanıt alanları

Alan Tip Açıklama
invoice_id string Önekli fatura kimliği (inv_...)
project_id string Önekli proje kimliği (prj_...)
status string Fatura durumu (snake_case — bkz. Fatura Durumları)
is_final boolean Faturanın nihai durumda olup olmadığı
is_test boolean Sandbox faturaları için true
payment_url string Ödeme URL'si: Telegram botu projesinde Paymos botunu açan bağlantı, diğer tüm projelerde barındırılan ödeme sayfası
order object Satıcıya dönük sipariş verisi
order.external_id string Satıcı sipariş kimliği
order.client_id string? Satıcı müşteri kimliği
order.amount string İstenen tutar
order.currency string Satıcının istediği fiat para birimi kodu veya kripto varlık sembolü
order.network string? Doğrudan kripto faturaları için istenen ağ
payment object? Ödeme ayrıntıları — token ve ağ seçildiğinde mevcut olur. Yatırma adresini, beklenen kripto tutarını, kilitlenen kuru ve transfer bazında ilerlemeyi tutar. Tüm alt alan referansı için bkz. Fatura Getir → Ödeme alanları
created_at integer Unix zaman damgası, saniye
updated_at integer Unix zaman damgası, saniye
expires_at integer Unix zaman damgası, saniye. Oluşturma anında belirlenir; bu yüzden her durumdaki her faturada mevcuttur
completed_at integer? Tamamlanma zaman damgası

Fatura durumları

Her fatura bir status dizesi bildirir. Aynı değer; satıcı API yanıtını, SSE ödeme akışını ve webhook yükünü yönetir — tek bir doğruluk kaynağı vardır. Aşağıdaki tablo durum bazlı referanstır: değerin ne zaman göründüğü, nihai olup olmadığı ve arkasındaki kesin koşul. Geçiş diyagramı ve iki oluşturma akışı için bkz. Ödeme akışı.

Nihai bir durum kesindir: fatura orada sonuçlanır ve bir daha asla hareket etmez. Beş durum nihai'dir — paid, paid_over, underpaid, expired, cancelled.

Durum Nihai Ne zaman geçerli
awaiting_client Hayır Her faturanın açılış durumu. Henüz token veya ağ seçilmediği için yatırma adresi yoktur. İptal yalnızca burada mümkündür
awaiting_payment Hayır Token, ağ ve yatırma adresi sabitlendi. Paymos, gelen transfer için adresi izliyor
confirming Hayır Bir transfer zincire düştü ve tutar kademesinin gerektirdiği onayları biriktiriyor
underpaid_waiting Hayır Beklenenden az tutar onaylandı ve fatura kalan için açık kalıyor. Yalnızca allow_multiple_payments true olduğunda ulaşılır
underpaid Evet Fatura eksik kapandı — ya beklenen tutarın altında süresi doldu ya da allow_multiple_payments false iken tek ödeme eksik kaldı
expired Evet Hiçbir şey alınmadan süre doldu veya fiat akışında token seçim penceresi token seçilmeden kapandı
cancelled Evet Satıcı, fatura hâlâ awaiting_client durumundayken iptal etti

İdempotency

Fatura oluştururken her zaman external_order_id gönderin. Aynı external_order_id ile aynı çağrının yeniden denenmesi, mevcut faturayı döndürür — asla kopya oluşturmaz. Yanıt durumu, idempotent eşleşmede 200 OK, yeni faturada 201 Created olur.

Bu; kararsız ağlara, çöken worker'lara ve yeniden deneme döngülerine karşı güvenlik ağınızdır. Aynı iş olayı için aynı ID'yi kullanın; yeni bir olay için yeni bir ID seçin.

UUID v4 veya kendi sipariş ID'nizi kullanın — iş olayı başına kararlı ve benzersiz herhangi bir değer. Bir ID'yi yanlışlıkla yeniden kullanırsanız yeni bir fatura değil, o ID'nin mevcut faturasını geri alırsınız (yukarıdaki 200 OK idempotent eşleşme).

Hatalar

Tam katalog için Hata Kodları bölümüne bakın. Her hata yanıtındaki type URI'si, ilgili satıra doğrudan bağlanır.