PaymentCenter/app/third/paymentService/psbc/README.md

192 lines
4.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Payment SDK
支付能力独立 SDK封装邮储手机银行支付、查询、退款、对账单、回调验签等能力供支付中心或其他业务系统复用。
## 功能特性
- 支付链接生成SM2+SM4 加密)
- 订单支付状态查询
- 退款申请
- 对账单查询与下载
- 回调通知验签与解密
- 工具方法订单号生成、Map 转签名字符串、HMAC-SHA256 签名
## 快速开始
### 1. 初始化客户端
```go
import "qteam/app/sdk/payment"
cfg := payment.Config{
MerchantId: "yourMerchantId",
MchtNo: "yourMchtNo",
AppID: "yourAppId",
SopPublicKey: "yourSopPublicKey",
PrivateKey: "yourPrivateKey",
Pubkey: "yourPubkey",
BankKey: "yourBankKey",
Sha: "yourShaKey",
ReturnUrl: "https://your-domain.com/return",
SuccessUrl: "https://your-domain.com/success",
NotifyUrl: "https://your-domain.com/notify",
ShowTitleBar: "1",
LoginHost: "https://login.example.com/",
OrderHost: "https://order.example.com/",
FileHost: "https://file.example.com/",
ShopId: "yourShopId",
}
client := payment.NewClient(cfg)
```
### 2. 创建支付链接
```go
link, err := client.CreatePaymentLink(payment.PaymentLinkRequest{
OrderNo: payment.GenerateOrderNumber(),
ProductName: "测试商品",
Price: "19.90",
BackUrl: "https://mall.example.com/pay",
})
if err != nil {
log.Fatal(err)
}
fmt.Println("支付链接:", link.PayUrl)
fmt.Println("订单号:", link.OrderNo)
fmt.Println("前端验签:", link.Sign)
```
### 3. 查询订单
```go
result, err := client.OrderQuery("SJ20240101000000001")
if err != nil {
log.Fatal(err)
}
fmt.Println("订单状态:", result.OrderSta)
fmt.Println("响应码:", result.RespCode)
```
### 4. 申请退款
```go
refund, err := client.Refund(payment.RefundRequest{
OrderNo: "SJ20240101000000001",
Price: "19.90",
OrgTxnSeq: "bankOrderNo123",
RefundDesc: "用户主动退款",
})
if err != nil {
log.Fatal(err)
}
fmt.Println("退款订单号:", refund.RefundOrderNo)
fmt.Println("退款状态:", refund.RefundOrderSta)
```
### 5. 对账单查询与下载
```go
// 查询对账单
bill, err := client.BillQuery(time.Now())
if err != nil {
log.Fatal(err)
}
// 下载对账单
for _, file := range bill.Files {
fileId := file["fileId"].(string)
data, err := client.BillDownload(fileId, time.Now())
if err != nil {
log.Fatal(err)
}
// 处理对账单数据
}
```
### 6. 处理回调通知
```go
// 解密通知
decrypted, err := client.DecryptNotify(rawJson)
if err != nil {
log.Fatal(err)
}
// 验签并解析
notifyData, err := client.VerifyAndParseNotify(rawJson)
if err != nil {
log.Fatal(err)
}
fmt.Println("通知数据:", notifyData)
```
## 核心类型说明
### Config
支付配置包含商户信息、密钥、URL 等必要配置。
### PaymentLinkRequest
```go
type PaymentLinkRequest struct {
OrderNo string
ProductName string
Price string
BackUrl string
}
```
### PaymentLinkResponse
```go
type PaymentLinkResponse struct {
OrderNo string
NotifyUrl string
Sign string
PlainText string
PayUrl string
}
```
### OrderQueryResponse
```go
type OrderQueryResponse struct {
OrderNo string
OrderSta string
RespCode string
RespMsg string
}
```
### RefundResponse
```go
type RefundResponse struct {
RespCode string
RespMsg string
RefundOrderNo string
RefundOrderSta string
TxnAmt string
}
```
## 注意事项
1. **密钥安全**:私钥、公钥等敏感信息请通过配置中心或环境变量传入,不要硬编码在代码中。
2. **并发安全**`GenerateOrderNumber` 和 `RandomNumber` 基于时间戳生成,高并发场景下建议由调用方保证唯一性。
3. **错误处理**:所有接口均返回 `error`,调用方需根据业务场景处理重试、降级等逻辑。
4. **状态码映射**:邮储订单状态码 `03-支付成功`、`04-支付失败`、`05-检查失败` 等,请参考 `types.go` 中的常量定义。
## 与现有系统集成建议
- **支付中心**:可直接使用此 SDK 封装统一支付服务。
- **业务系统**:通过依赖此 SDK 接入支付能力,避免重复实现加密、验签逻辑。
- **测试环境**:可通过 `Config` 切换测试环境地址和密钥。