跳到正文

Host-to-Host API

自建您的收银台

纯 REST 原语 + HMAC 签名 webhook。自带前端,自己渲染付款流程,掌控体验的每个环节。同一个 Paymos 后端,界面完全由您控制。

自建您的收银台

如何运作

三次调用,中间是您的界面

后端创建账单,自己渲染付款界面,付款确认后收到签名事件。边界干净利落。

  1. 1

    创建账单

    从后端 POST 到 /v1/invoices。传入金额、币种、您自己的外部订单号。拿回账单 ID 和它的 payment_url。

  2. 2

    渲染自己的界面

    在您这边收下代币和网络,再从服务端确认——这一步的返回里就带着收款地址。地址、二维码、倒计时,按您产品的样子展示。

  3. 3

    接收签名 webhook

    付款确认后,Paymos 向您的接口 POST 一个 HMAC 签名事件。验证签名,标记订单已支付,返回 200。

上线前试遍每个调用

控制台 Playground 用您的测试 API 密钥发起真实沙盒请求。选接口、填参数、点发送——实时看到 HMAC 签名、请求头和响应。不用 Postman,不用 curl,不用从文档复制粘贴。

三次调用,中间是您的界面

界面掌控

当托管页面不够用

适合在 API 之上自建付款表单的团队——像素级贴合品牌,并接入自己的系统。当现成界面都不合适时,就该用 Host-to-Host。

完全掌控界面

钱包选择器、二维码、状态更新都自己渲染。您的设计体系,您的交互语言,您的品牌。

原生适配任何技术栈

Node、Python、PHP、Go、Ruby、Java、.NET——任何能说 HTTP 的都行。没有 SDK 绑定。

签名 webhook,带重试

HMAC 签名载荷,至少一次投递,指数退避重试。验证在您一侧,去重在您一侧。

沙盒环境

测试模式与生产并排。同样的接口,隔离的数据,没有真实资金流动。

您掌控什么

界面您渲染,链我们盯

边界清晰:您的前端负责客户看到的每个像素;我们的基础设施负责地址派生、链上监控、确认深度和结算。

您的界面

钱包选择器、网络选择器、地址展示、二维码生成、状态反馈——全部由您设计。

您的流程

步骤顺序按产品需要编排。把付款并入注册流程、拆到多个屏幕、放在登录之后。

您的品牌

客户的 URL 和视觉画面里从不出现 Paymos。付款界面完全白标。

您的结算

按您的节奏转出到资金库钱包。与其他 Paymos 界面结算进同一个余额账本。

开始使用

同一个后端,没有 SDK 要学

通过 REST 创建账单,轮询状态或订阅 webhook,渲染任何合适的界面。文档里有九种语言示例,所有接口同一套签名方案。

阅读文档
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);

一套签名方案

HMAC-SHA256 加共享密钥。创建账单、查询状态、转出、webhook 验证都是同一套——只需维护一条验证管道。

平台级集成

多项目账户、按范围授权的 API 密钥、通过 external_order_id 幂等创建账单。按您的方式自建收银台——API 保持不变。

谁在用 Host-to-Host

为有专用付款界面的产品而生

任何托管界面太受限、而团队又有工程能力自建的地方。加密货币交易所、托管钱包、交易平台、入金通道。

加密货币交易所

入金做成交易界面里的原生体验,而不是跳转到第三方。

托管钱包

充值流程完全留在您的钱包 App 内。不用跳浏览器,没有进程外步骤。

交易平台

保证金充值、入金对账、多账户结算——都由同一套 REST 原语驱动。

自建前端的平台

产品团队宁愿自己写付款界面,也不愿嵌一个现成的。地址、确认状态和已签名事件从 API 来;用户看到的那一屏由您自己的代码决定。

费率

每笔结算账单 1.0%,企业费率 0.3%

自建界面不改变费率,和其他接入方式是同样两个数。0.3% 的那一档要单独申请。

查看费率

今天就在 Paymos API 上自建收银台