Bu sayfada
Yatırma akışı
Onaylanmış kanal yatırmalarını yayın sırasıyla, hep ilerleyen bir imleçle sorgulayın; kesinleşmiş hiçbir ödeme atlanmaz veya sessizce tekrarlanmaz.
API anahtarı: Payment
Bu bir entegrasyon akışıdır, geçmiş sayfası değil. Yalnızca onaylanmış yatırmaları, en eskiden başlayarak, genel bir yayın sırasıyla döndürür ve her zaman bir imleç verir. Belirli aralıklarla sorgularsanız kesinleşmiş her ödemeyi tam olarak bir kez ve sonradan bozulmayan bir sırayla görürsünüz.
Webhook'lar hızlı yoldur; bu akış ise güvenilir yol. İkisini birlikte çalıştırın: webhook'lar size saniyeleri kazandırır, akış ise uç noktanız kapalı kalmış olsa bile her şeyi eninde sonunda gördüğünüzü garanti eder.
Sorgu parametreleri
| Parametre | Tip | Varsayılan | Açıklama |
|---|---|---|---|
limit |
integer | 20 |
1 ile 100 arasında sayfa boyutu. |
cursor |
string | — | Bir önceki sayfanın next_cursor değerinden gelen opak imleç. |
project_id |
string | — | Tek bir projeyle sınırlar (prj_…). |
payment_channel_id |
string | — | Tek bir kanalla sınırlar (pc_…). |
confirmed_from |
integer | — | Unix saniye; yalnızca bu andan itibaren onaylanmış yatırmalar. Yalnızca ilk sorguyu sınırlar — aşağıya bakın. |
status parametresi bilinçli olarak yoktur. confirming sorgulayabilen bir istemci, bir reorg'un hâlâ geri alabileceği parayı kesinleşmiş saymış olurdu.
Örnek
GET /v1/payment-channel-deposits?limit=100&cursor=CfDJ8JvN… HTTP/1.1
Host: api.paymos.io
Authorization: HMAC-SHA256 pk_live_…:…
X-Request-Timestamp: 1767225660
Kod örnekleri
Her sekme ilgili dilin resmî SDK'sını kullanır. İmzalama, serileştirme, güvenli yeniden denemeler ve tiplenmiş hatalar SDK tarafından yürütülür.
API_KEY_ID="pk_live_xxxxxxxxxxxx"
API_SECRET="sk_live_xxxxxxxxxxxx"
QUERY="?limit=100"
TS=$(date +%s)
# No body: the hash slot is the EMPTY STRING, not sha256("") — its fixed
# e3b0c442… digest signs a different payload and the request is rejected. The
# query keeps its leading "?" exactly as transmitted.
SIGNATURE=$(printf '%s\n%s\n%s\n%s\n%s' "$TS" GET /v1/payment-channel-deposits "$QUERY" '' \
| openssl dgst -sha256 -hmac "$API_SECRET" -binary | base64)
curl -sS "https://api.paymos.io/v1/payment-channel-deposits$QUERY" \
-H "Authorization: HMAC-SHA256 $API_KEY_ID:$SIGNATURE" \
-H "X-Request-Timestamp: $TS"
import { Paymos } from '@paymos/sdk';
const paymos = new Paymos({
apiKey: process.env.PAYMOS_API_KEY,
apiSecret: process.env.PAYMOS_API_SECRET,
});
const page = await paymos.paymentChannelDeposits.read({ limit: 100 });
for (const deposit of page.items) {
console.log(deposit.id, deposit.net, deposit.currency);
}
console.log('resume from', page.nextCursor);
import os
from paymos import Paymos
paymos = Paymos(
api_key=os.environ["PAYMOS_API_KEY"],
api_secret=os.environ["PAYMOS_API_SECRET"],
)
page = paymos.payment_channel_deposits.read(limit=100)
for deposit in page["items"]:
print(deposit["id"], deposit["net"], deposit["currency"])
print("resume from", page["next_cursor"])
<?php
use Paymos\Client;
use Paymos\ClientConfig;
$paymos = new Client(new ClientConfig(
getenv('PAYMOS_API_KEY'),
getenv('PAYMOS_API_SECRET')
));
$page = $paymos->paymentChannelDeposits()->readPage(array('limit' => 100));
foreach ($page['items'] as $deposit) {
echo $deposit['id'] . ' ' . $deposit['net'] . ' ' . $deposit['currency'] . PHP_EOL;
}
echo 'resume from ' . $page['next_cursor'] . PHP_EOL;
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)
}
page, err := client.PaymentChannelDeposits.Read(context.Background(), paymos.PaymentChannelDepositFeedParams{
Limit: 100,
})
if err != nil {
panic(err)
}
for _, deposit := range page.Items {
fmt.Println(deposit.ID, deposit.Net, deposit.Currency)
}
fmt.Println("resume from", page.NextCursor)
}
using Paymos;
using var paymos = new PaymosClient(
Environment.GetEnvironmentVariable("PAYMOS_API_KEY")!,
Environment.GetEnvironmentVariable("PAYMOS_API_SECRET")!);
var page = await paymos.PaymentChannelDeposits.ReadAsync(
new PaymentChannelDepositFeedOptions(Limit: 100));
foreach (var deposit in page.Items)
{
Console.WriteLine($"{deposit.Id} {deposit.Net} {deposit.Currency}");
}
Console.WriteLine($"resume from {page.NextCursor}");
import io.paymos.PaymentChannelDeposit;
import io.paymos.PaymentChannelDepositFeedOptions;
import io.paymos.PaymentChannelDepositFeedPage;
import io.paymos.PaymosClient;
PaymosClient paymos = new PaymosClient(
System.getenv("PAYMOS_API_KEY"),
System.getenv("PAYMOS_API_SECRET"));
PaymentChannelDepositFeedPage page = paymos.paymentChannelDeposits.read(
PaymentChannelDepositFeedOptions.builder().limit(100).build());
for (PaymentChannelDeposit deposit : page.items()) {
System.out.println(deposit.id() + " " + deposit.net() + " " + deposit.currency());
}
System.out.println("resume from " + page.nextCursor());
require 'paymos'
paymos = Paymos::Client.new(
api_key: ENV.fetch('PAYMOS_API_KEY'),
api_secret: ENV.fetch('PAYMOS_API_SECRET')
)
page = paymos.payment_channel_deposits.read(limit: 100)
page.items.each do |deposit|
puts "#{deposit.id} #{deposit.net} #{deposit.currency}"
end
puts "resume from #{page.next_cursor}"
use paymos::{PaymentChannelDepositFeedParams, PaymosClient};
let paymos = PaymosClient::new(
std::env::var("PAYMOS_API_KEY")?,
std::env::var("PAYMOS_API_SECRET")?,
)?;
let page = paymos
.payment_channel_deposits()
.read(&PaymentChannelDepositFeedParams {
limit: Some(100),
..Default::default()
})
.await?;
for deposit in &page.items {
println!("{} {} {}", deposit.id, deposit.net, deposit.currency);
}
println!("resume from {}", page.next_cursor);
Yanıt (200 OK)
{
"items": [
{
"id": "pcd_8ScRvL4jNq2XkB7mTfZdWu",
"payment_channel_id": "pc_2QhKZv6mRt9WdA3nYpLbXf",
"project_id": "prj_xFukZuAJZR06pLVBh3uwzv",
"payment_channel_external_id": "customer-42",
"status": "confirmed",
"is_final": true,
"is_test": false,
"currency": "USDT",
"network": "TRC20",
"chain_id": 728126428,
"contract_address": "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t",
"gross": "100",
"fee": "1",
"net": "99",
"applied_fee_percent": 1.0,
"customer_fee_percent": 0,
"tx_hash": "9f4c1b7e30ad52c8ef6a1d84b0c39f27a5e6d138f4b90c72ae51d63b8407fc25",
"transfer_id": "9f4c1b7e30ad52c8ef6a1d84b0c39f27a5e6d138f4b90c72ae51d63b8407fc25:41a614f803b6fd780986a42c78ec9c7f77e6ded13c:41c9f6a2b7d0138e54ca3b91f6072ed48a5c1e93b7:0",
"source_address": "TW9s4RkAqBnLpVdX2ChYzUeGm7QfKt3NbZ",
"destination_address": "TN3W4H6rK2ce4vX9YnFQHwKENnHjoxb3m9",
"block_height": 68421905,
"first_included_block_timestamp": 1767225900,
"explorer_url": "https://tronscan.org/#/transaction/9f4c1b7e30ad52c8ef6a1d84b0c39f27a5e6d138f4b90c72ae51d63b8407fc25",
"created_at": 1767225870,
"updated_at": 1767225930,
"confirmed_at": 1767225930
},
{
"id": "pcd_5NmXqW7bHt3ZjR9kCvPyAe",
"payment_channel_id": "pc_2QhKZv6mRt9WdA3nYpLbXf",
"project_id": "prj_xFukZuAJZR06pLVBh3uwzv",
"payment_channel_external_id": "customer-42",
"status": "confirmed",
"is_final": true,
"is_test": false,
"currency": "USDC",
"network": "ERC20",
"chain_id": 1,
"contract_address": "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
"gross": "42.5",
"fee": "0.425",
"net": "42.075",
"applied_fee_percent": 1.0,
"customer_fee_percent": 0,
"tx_hash": "0x1d7b64e2c05af398b2e714cd9a06f3518cb7e2409df6a1c8305b47ed12f9ca63",
"transfer_id": "0x1d7b64e2c05af398b2e714cd9a06f3518cb7e2409df6a1c8305b47ed12f9ca63:0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48:0x9f2a6c1b4e8d7350ab11c9e5f0d2743b86ce41d9:0",
"source_address": "0x4b8e1f60d3a97c25be04f7183a5cd9027ef6b14a",
"destination_address": "0x9f2a6c1b4e8d7350ab11c9e5f0d2743b86ce41d9",
"block_height": 22984117,
"first_included_block_timestamp": 1767226020,
"explorer_url": "https://etherscan.io/tx/0x1d7b64e2c05af398b2e714cd9a06f3518cb7e2409df6a1c8305b47ed12f9ca63",
"created_at": 1767226020,
"updated_at": 1767226260,
"confirmed_at": 1767226260
}
],
"next_cursor": "CfDJ8JvN…"
}
Akışı doğru sorgulama
- 01İmleçsiz başlayın. Sayfanın tamamını işleyin.
- 02
next_cursordeğerini, sayfa tümüyle işlendikten sonra kalıcı olarak saklayın; öncesinde değil. - 03Bir sonraki sorguda geri gönderin. Tekrarlayın.
Bu üç adımın arkasındaki sözleşme:
- —
next_cursoraslanullolmaz. Boş sayfa dahil her yanıtta bulunur. Konumlar satıcı başına değil, geneldir; bu yüzden hiçbir şeyle eşleşmeyen bir filtrenin bile atladığı konumların ötesine geçmesi gerekir — boşta duran bir entegrasyon da aynı aralığı sonsuza dek yeniden taramaz. - —
nullimleçte değil, boş ya da eksik sayfada durun. Fatura listesinext_cursornullolduğunda biter; bu akışın öyle bir sonu yoktur ve bu koşulla yazılan döngü hiç bitmez.limitdeğerinden az kayıt gelmesi, şu an size kalan bir şey olmadığı anlamına gelir: imleci saklayın, döngüden çıkın ve kendi takviminize göre yeniden sorgulayın. - —
confirmed_fromyalnızca ilk sorguyu sınırlar. İkinci sorgudan itibaren nereden devam edeceğinizi saklanan imleç belirler. Aynı değeri imleçle birlikte değiştirmeden göndermeye devam edin: imlecin bağlı olduğu bilgilerden biri de odur, dolayısıyla değeri kaldırmak veya ileri taşımak imleci geçersiz kılar. - —Sıra monotondur. Bir yatırma bir kez, sabit bir konumda yayımlanır; sonraki bir onay, daha önce okuduğunuz bir onaydan önce görünemez.
- —İlerlemek sizin kararınız. Eski bir imleci yeniden denerseniz aynı yatırmaları tekrar görebilirsiniz.
idüzerinden yinelenenleri ayıkladığınız sürece bu güvenlidir —pcd_kimliği webhook teslimi, akış teslimi ve her tekrar arasında aynı kalır. - —İmleçlerin süresi 24 saat sonra dolar; bu yüzden işi günde en az bir kez çalışacak şekilde planlayın. İmleç, kaldığınız yerdir; bir hafta rafa kaldırılacak yer imi değil. Daha uzun süre sessiz kalan bir okuyucu
400 pagination_cursor_invalidalır veconfirmed_fromile sınırlanmış biçimde baştan başlar. - —İmleç ayrıca bağlıdır: kimlik bilginize, onun ortamına, proje kapsamına ve gönderdiğiniz filtrelere. Bir filtreyi değiştirir ya da anahtarın proje erişimini genişletirseniz eski imleç aynı şekilde reddedilir. İlk sayfadan yeniden başlayın:
pcd_üzerinden yinelenenleri ayıkladığınız için tam bir yeniden senkronizasyon zararsızdır.
Akış durduğunda
Tek bir yatırma yanıta dönüştürülemiyorsa akış onu atlamaz ve sayfayı hataya düşürmez. Öncesindeki her şeyi teslim eder, next_cursor değerini o konumda tutar ve hangi yatırmanın neden takıldığını söyler:
{
"items": [],
"next_cursor": "CfDJ8JvN…",
"blocked": {
"deposit_id": "pcd_4KdQzT9rVn6WsB1mYhFxLg",
"reason": "booked_auth_missing"
}
}
blocked, normal hiçbir sayfada bulunmaz. Bulunduğunda:
| Neden | Anlamı |
|---|---|
booked_auth_missing |
Ödeme onaylandı, ancak muhasebe kaydı henüz yazılmadı. |
inconsistent |
Yatırma, kanalı ve zincir kaydı birbiriyle çelişiyor. |
deposit_missing |
Yayımlanan kayıt artık bir yatırmaya çözülmüyor. |
channel_missing |
Yatırmanın kanalı yüklenemedi. |
transfer_missing |
Yatırmanın kanıtını alacağı bağlı bir zincir kaydı yok. |
not_confirmed |
Yayımlanan bir yatırma onaylanmış durumda değil; bu akışa yalnızca nihai para girer. |
Sorgulamayı sürdürün. next_cursor, bilinçli olarak takılan konumun gerisinde kalır; alttaki kayıt onarıldığı anda akış kendiliğinden devam eder ve arada hiçbir şey kaybolmaz. Bunların hepsi bizim tarafımızdaki operasyonel arızadır — sürerse deposit_id ile destekle iletişime geçin.
Hatalar
| Kod | HTTP | Ne zaman |
|---|---|---|
payment_channels_disabled |
503 | Ödeme kanalları, bu ortamda hesabınız için etkin değil. |
payment_key_required |
403 | İstek, Payout (rk_) anahtarıyla imzalandı. |
pagination_cursor_invalid |
400 | İmleç bozuk, süresi dolmuş ya da farklı filtrelere veya farklı bir kapsama bağlı. |
field_invalid_format |
400 | project_id veya payment_channel_id geçerli bir önekli kimlik değil. |
field_out_of_range |
400 | limit, 1–100 aralığının dışında. |
query_parameter_unknown |
400 | Yukarıdaki tabloda bulunmayan bir parametre. |
Tam katalog için bkz. Hata Kodları.