Integrasi

Pembayaran kripto untuk backend kustom

Panduan bebas-stack untuk mengintegrasikan Qvard ke server Anda sendiri: model pesanan, membuat pembayaran, webhook, rekonsiliasi, dan daftar periksa sebelum meluncur, dengan contoh Python.

Jika toko, layanan, atau platform Anda berjalan di backend sendiri, Anda tidak memerlukan plugin: Qvard hanya membutuhkan satu panggilan yang membuat pembayaran dan satu endpoint yang menerima hasilnya. Panduan ini menelusuri integrasi dengan cara yang cocok untuk bahasa dan framework apa pun, dengan contoh Python, dan mencakup bagian yang membuatnya andal: model pesanan, idempotensi, rekonsiliasi, dan daftar periksa singkat sebelum meluncur.

Yang Anda butuhkan

  • Akun Qvard dengan proyek, kunci API, dan callback URL webhook Anda yang tersimpan di proyek.
  • Endpoint HTTPS publik di server Anda untuk webhook.
  • Tabel pesanan (atau padanannya) tempat sebuah pembayaran dapat dicocokkan dengan pesanan lewat pengenal Anda sendiri.

Belum ada SDK dan sandbox: integrasinya HTTP biasa, dan pengujian dilakukan dengan jumlah kecil yang nyata. Referensi format permintaan ada di API pembayaran kripto untuk developer; panduan ini menunjukkan bagaimana semuanya menyatu.

Model pesanan minimal

Data Anda sendiri menentukan seberapa bersih integrasinya. Kumpulan field minimal pada pesanan:

  • id: nomor pesanan atau faktur Anda. Itulah id yang Anda kirim ke Qvard dan kunci yang kembali di webhook.
  • amount_usd: jumlah dalam dolar AS, satuan tempat pembayaran dibuat.
  • state: misalnya awaiting_payment, paid, cancelled. Tandai dibayar hanya dari webhook.
  • paid_at dan, bila mau, id pembayaran Qvard dari respons untuk dukungan.

Hindari menaruh seluruh logika pembayaran di kelas pesanan. Modul kecil yang membuat pembayaran dan endpoint yang menerapkan webhook menjaga kode tetap dapat diuji.

Membuat pembayaran

Saat pelanggan memilih membayar, buat pembayaran dari backend Anda dengan satu POST ke https://api.qvard.com/api/v1/payment. Kirim kunci di header Authorization: Bearer dan JSON dengan nomor pesanan sebagai id (string), jumlah sebagai price dalam dolar AS, dan opsional paymentSystemId untuk membuka halaman pembayaran dengan aset dan jaringan terpilih.

Responsnya 201 dengan redirectUrl, alamat halaman pembayaran yang dihosting. Arahkan pelanggan ke sana, atau taruh tautan di email. Aturan yang layak dikodekan di klien:

  • Timeout dan percobaan ulang. Gunakan timeout dan ulangi saat timeout atau 5xx. Mengirim id yang sama untuk metode pembayaran yang sama mengembalikan pembayaran yang ada, sehingga pengulangan tidak dapat membuat yang kedua.
  • Jangan ulangi 400 («Error validation», dengan pesan per field) atau 401 (kunci salah) tanpa mengubah sesuatu.
  • Jumlah dalam dolar. Jika toko Anda memberi harga dalam mata uang lain, konversikan sebelum panggilan.
Pythonqvard_client.py
import os
import requests

QVARD_URL = "https://api.qvard.com/api/v1/payment"

def create_payment(order_id: str, amount_usd: float) -> str:
    """Create a Qvard payment for an order and return the hosted payment page URL."""
    response = requests.post(
        QVARD_URL,
        headers={"Authorization": "Bearer " + os.environ["QVARD_API_KEY"]},
        json={"id": order_id, "price": amount_usd},   # id as a string, price in US dollars
        timeout=15,
    )
    if response.status_code == 201:
        return response.json()["redirectUrl"]
    # 400 = "Error validation" with a per-field message, 401 = wrong API key
    raise RuntimeError(f"Qvard {response.status_code}: {response.text}")

Menerima webhook

Saat pembayaran selesai, Qvard mengirim POST ke callback URL Anda dengan id dan status, ditandatangani di header X-Qvard-Signature. Endpoint Anda harus:

  1. Memverifikasi tanda tangan: HMAC-SHA256 dengan kunci rahasia Anda atas timestamp dan body mentah, dibandingkan dalam waktu konstan; jika tidak cocok, menjawab 400.
  2. Bertindak hanya pada status completed.
  3. Memperbarui pesanan secara bersyarat, «dibayar jika masih menunggu pembayaran», sehingga pengulangan tidak melakukan apa-apa.
  4. Mengantrekan pekerjaan lambat dan menjawab tepat HTTP 200.

Qvard mengulang jawaban lain apa pun, timeout, atau pengalihan, lima percobaan dalam sekitar enam menit, jadi pengiriman berulang itu normal. Detail percobaan ulang ada di strategi percobaan ulang webhook pada sistem pembayaran, dan aturan keamanan di cara mengamankan webhook pembayaran kripto.

Pythonwebhook.py
import os
from fastapi import FastAPI, Request, Response
from qvard import Qvard

app = FastAPI()
qvard = Qvard(os.environ["QVARD_API_KEY"])

@app.post("/webhooks/qvard")
async def qvard_webhook(request: Request):
    try:
        body = qvard.webhooks.construct_event(await request.body(), request.headers.get("X-Qvard-Signature"), os.environ["QVARD_API_KEY"])
    except ValueError:
        return Response(status_code=401)

    if body.get("status") == "completed":
        # Only changes an order that is not paid yet, so repeated deliveries are harmless.
        changed = await db.execute(
            "UPDATE orders SET state = 'paid', paid_at = now() WHERE id = :id AND state = 'awaiting_payment'",
            {"id": body.get("id")},
        )
        if changed:
            await queue.enqueue("fulfil_order", body["id"])

    return Response(status_code=200)

Pembayaran sebagian, kegagalan, dan tampilan pelanggan

Putuskan apa arti setiap status pembayaran bagi pesanan:

  • wait: menunggu pembayaran.
  • partial: yang tiba kurang dari jumlah penuh; webhook penyelesaian tidak dikirim. Biarkan pesanan terbuka, beri tahu pelanggan berapa yang kurang, atau batalkan dan kembalikan dana.
  • completed: jumlah penuh tiba; tandai pesanan dibayar.
  • rejected: tawarkan cara bayar lain.

URL kembali setelah pembayaran belum tersedia, jadi pelanggan kembali sendiri: beri mereka halaman pesanan yang menampilkan status sebenarnya dan menyegarkan diri selama menunggu. Pengembalian dana adalah transfer yang Anda kirim sendiri, karena pembayaran kripto tidak dapat dibatalkan.

Rekonsiliasi dan daftar periksa sebelum meluncur

Tambahkan pemeriksaan harian yang membandingkan pesanan yang Anda anggap dibayar atau tidak dengan pembayaran dan saldo di panel Qvard; pembayaran yang tampak selesai sementara pesanan Anda belum dibayar adalah notifikasi yang terlewat, yang bisa Anda kirim ulang dari panel.

Sebelum meluncur:

  • kunci API ada di variabel lingkungan atau pengelola rahasia, tidak pernah di repositori;
  • callback URL tersimpan, publik, HTTPS, dan dapat dijangkau dari luar jaringan Anda;
  • endpoint menjawab tepat 200, cepat, dan aman bila dijalankan dua kali;
  • Anda membayar sejumlah kecil uang sungguhan dan melihat pesanan menjadi dibayar;
  • Anda membuat endpoint gagal sekali dan melihat Qvard mengulang tanpa pemenuhan ganda;
  • Anda menarik sejumlah kecil ke dompet Anda. Penarikan hanya dikenai biaya jaringan; penarikan ke rekening bank dalam fiat tidak tersedia.

Ketentuan komersial ada di halaman harga, dan faktur demo menunjukkan apa yang dilihat pelanggan Anda.

FAQ

Apakah ada SDK untuk bahasa saya?

Tidak. Integrasinya HTTP biasa: satu POST untuk membuat pembayaran dan satu webhook untuk menerima hasilnya. Contoh di panduan ini menunjukkan polanya di Python, dan bisa dipindahkan ke bahasa apa pun.

Bagaimana cara mencocokkan pembayaran dengan pesanan?

Kirim nomor pesanan Anda sendiri sebagai id saat membuat pembayaran. Id yang sama kembali di webhook.

Apakah ada sandbox untuk pengujian?

Belum. Gunakan jumlah kecil yang nyata dan faktur demo untuk melihat halaman pembayaran.

Bagaimana jika server saya mati saat pembayaran selesai?

Qvard mengulang lima kali dalam sekitar enam menit. Setelah itu, kirim ulang notifikasi pembayaran dari panel; handler idempoten membuatnya aman.

Artikel terkait

Artikel terkait