227 lines
6.9 KiB
Go
227 lines
6.9 KiB
Go
package paymentService
|
|
|
|
import (
|
|
"PaymentCenter/app/third/paymentService/payCommon"
|
|
psbc "PaymentCenter/app/third/paymentService/psbc"
|
|
"PaymentCenter/config"
|
|
"context"
|
|
"encoding/json"
|
|
"fmt"
|
|
"github.com/qit-team/snow-core/log/logger"
|
|
"strconv"
|
|
)
|
|
|
|
type PsbcPay struct {
|
|
MerchantId string `json:"merchant_id"` // 商户ID
|
|
MchtNo string `json:"mcht_no"` // 商户号
|
|
AppID string `json:"app_id"` // 应用ID
|
|
SopPublicKey string `json:"sop_public_key"` // SOP公钥
|
|
PrivateKey string `json:"private_key"` // 商户私钥
|
|
Pubkey string `json:"pubkey"` // 商户公钥
|
|
BankKey string `json:"bank_key"` // 银行公钥
|
|
Sha string `json:"sha"` // SHA密钥
|
|
ReturnUrl string `json:"return_url"` // 支付返回地址
|
|
SuccessUrl string `json:"success_url"` // 支付成功地址
|
|
NotifyUrl string `json:"notify_url"` // 回调通知地址
|
|
ShowTitleBar string `json:"show_title_bar"` // 是否显示标题栏
|
|
LoginHost string `json:"login_host"` // 登录服务地址
|
|
OrderHost string `json:"order_host"` // 订单服务地址
|
|
FileHost string `json:"file_host"` // 文件服务地址
|
|
ShopId string `json:"shop_id"` // 店铺ID
|
|
Psbcmcc string `json:"psbcmcc"` // 三方服务商标识
|
|
}
|
|
|
|
func PsbcInitClient(psbcConfig PsbcPay) *psbc.Client {
|
|
cfg := psbc.Config{
|
|
MerchantId: psbcConfig.MerchantId,
|
|
MchtNo: psbcConfig.MchtNo,
|
|
AppID: psbcConfig.AppID,
|
|
SopPublicKey: psbcConfig.SopPublicKey,
|
|
PrivateKey: psbcConfig.PrivateKey,
|
|
Pubkey: psbcConfig.Pubkey,
|
|
BankKey: psbcConfig.BankKey,
|
|
Sha: psbcConfig.Sha,
|
|
ReturnUrl: psbcConfig.ReturnUrl,
|
|
SuccessUrl: psbcConfig.SuccessUrl,
|
|
NotifyUrl: psbcConfig.NotifyUrl,
|
|
ShowTitleBar: psbcConfig.ShowTitleBar,
|
|
LoginHost: psbcConfig.LoginHost,
|
|
OrderHost: psbcConfig.OrderHost,
|
|
FileHost: psbcConfig.FileHost,
|
|
ShopId: psbcConfig.ShopId,
|
|
Psbcmcc: psbcConfig.Psbcmcc,
|
|
}
|
|
return psbc.NewClient(cfg)
|
|
}
|
|
|
|
func PsbcPayInfo(c context.Context, payOrderRequest PayOrderRequest) (string, error) {
|
|
envConfig := config.GetConf()
|
|
notifyUrl := fmt.Sprintf(envConfig.PayService.Host+payCommon.PSBC_NOTIFY_URL_TEST+"%d", payOrderRequest.PayChannelId)
|
|
|
|
psbcConfig := payOrderRequest.Psbc
|
|
psbcConfig.NotifyUrl = notifyUrl
|
|
psbcClient := PsbcInitClient(psbcConfig)
|
|
|
|
amount := fmt.Sprintf("%.2f", float64(payOrderRequest.Amount)/100.0)
|
|
orderNo := strconv.FormatInt(payOrderRequest.OrderId, 10)
|
|
|
|
req := psbc.PaymentLinkRequest{
|
|
OrderNo: orderNo,
|
|
ProductName: payOrderRequest.Description,
|
|
Price: amount,
|
|
BackUrl: payOrderRequest.ReturnUrl,
|
|
}
|
|
|
|
resp, err := psbcClient.CreateHandCodePayParams(req)
|
|
if err != nil {
|
|
logger.Error(c, "PsbcPayInfo 发生错误", fmt.Sprintf("错误信息:%s", err.Error()))
|
|
return "", err
|
|
}
|
|
|
|
respBytes, err := json.Marshal(resp)
|
|
if err != nil {
|
|
logger.Error(c, "PsbcPayInfo 序列化失败", fmt.Sprintf("错误信息:%s", err.Error()))
|
|
return "", err
|
|
}
|
|
return string(respBytes), nil
|
|
}
|
|
|
|
func PsbcOrderQuery(ctx context.Context, psbcConfig PsbcPay, orderNo string) (PayOrderQueryInfo, error) {
|
|
psbcClient := PsbcInitClient(psbcConfig)
|
|
|
|
resp, err := psbcClient.OrderQuery(orderNo)
|
|
if err != nil {
|
|
logger.Error(ctx, "PsbcOrderQuery 发生错误", fmt.Sprintf("错误信息:%s", err.Error()))
|
|
return PayOrderQueryInfo{}, err
|
|
}
|
|
|
|
tradeState := "NOTPAY"
|
|
tradeStateDesc := ""
|
|
switch resp.OrderSta {
|
|
case "03":
|
|
tradeState = "SUCCESS"
|
|
tradeStateDesc = "支付成功"
|
|
case "04", "05":
|
|
tradeState = "FAIL"
|
|
tradeStateDesc = "支付失败"
|
|
default:
|
|
tradeState = "NOTPAY"
|
|
tradeStateDesc = "未支付"
|
|
}
|
|
|
|
var amountTotal int64
|
|
var payerTotal int64
|
|
if resp.TxnAmt != "" {
|
|
amountFloat, err := strconv.ParseFloat(resp.TxnAmt, 64)
|
|
if err == nil {
|
|
amountTotal = int64(amountFloat * 100)
|
|
payerTotal = int64(amountFloat * 100)
|
|
}
|
|
}
|
|
|
|
successTime := ""
|
|
|
|
outTradeNo, _ := strconv.ParseInt(orderNo, 10, 64)
|
|
return PayOrderQueryInfo{
|
|
AppId: psbcConfig.AppID,
|
|
OutTradeNo: outTradeNo,
|
|
TransactionId: resp.OrderNo,
|
|
TradeState: tradeState,
|
|
TradeStateDesc: tradeStateDesc,
|
|
SuccessTime: successTime,
|
|
AmountTotal: amountTotal,
|
|
PayerTotal: payerTotal,
|
|
}, nil
|
|
}
|
|
|
|
func PsbcRefundOrder(ctx context.Context, orderRefundRequest OrderRefundRequest) (OrderRefundInfo, error) {
|
|
psbcClient := PsbcInitClient(orderRefundRequest.Psbc)
|
|
|
|
refundAmount := fmt.Sprintf("%.2f", float64(orderRefundRequest.RefundAmount)/100.0)
|
|
orderNo := strconv.FormatInt(orderRefundRequest.OrderId, 10)
|
|
|
|
req := psbc.RefundRequest{
|
|
OrderNo: orderNo,
|
|
Price: refundAmount,
|
|
OrgTxnSeq: orderRefundRequest.TransactionId,
|
|
RefundDesc: orderRefundRequest.RefundReason,
|
|
}
|
|
|
|
resp, err := psbcClient.Refund(req)
|
|
if err != nil {
|
|
logger.Error(ctx, "PsbcRefundOrder 发生错误", fmt.Sprintf("申请退款接口失败,错误信息:%s", err.Error()))
|
|
return OrderRefundInfo{}, err
|
|
}
|
|
|
|
refundStatus := payCommon.PAY_REFUND_STATU_COMMON
|
|
switch resp.RefundOrderSta {
|
|
case "03":
|
|
refundStatus = payCommon.PAY_REFUND_STATU_SUCCESS
|
|
case "04":
|
|
refundStatus = payCommon.PAY_REFUND_STATU_FAIL
|
|
}
|
|
|
|
refundFee := int64(0)
|
|
if resp.TxnAmt != "" {
|
|
amountFloat, err := strconv.ParseFloat(resp.TxnAmt, 64)
|
|
if err == nil {
|
|
refundFee = int64(amountFloat * 100)
|
|
}
|
|
}
|
|
|
|
return OrderRefundInfo{
|
|
OutTradeNo: orderRefundRequest.OrderId,
|
|
TransactionId: resp.RefundOrderNo,
|
|
RefundFee: refundFee,
|
|
RefundOrderId: orderRefundRequest.RefundOrderId,
|
|
RefundStatus: refundStatus,
|
|
RefundSuccessTime: "",
|
|
}, nil
|
|
}
|
|
|
|
func PsbcCloseOrder(ctx context.Context, orderCloseRequest OrderCloseRequest) (OrderCloseInfo, error) {
|
|
return OrderCloseInfo{
|
|
OutTradeNo: orderCloseRequest.OrderId,
|
|
}, nil
|
|
}
|
|
|
|
func PsbcVerifyAndParseNotify(rawBody string, psbcConfig PsbcPay) (orderId int64, amountTotal int64, payerTotal int64, status string, err error) {
|
|
psbcClient := PsbcInitClient(psbcConfig)
|
|
|
|
result, err := psbcClient.VerifyAndParseNotify(rawBody)
|
|
if err != nil {
|
|
logger.Error(context.Background(), "PsbcVerifyAndParseNotify 发生错误", fmt.Sprintf("验签解密失败,错误信息:%s", err.Error()))
|
|
return 0, 0, 0, "", err
|
|
}
|
|
|
|
orderId, err = strconv.ParseInt(result.ReqTraceId, 10, 64)
|
|
if err != nil {
|
|
logger.Error(context.Background(), "PsbcVerifyAndParseNotify 发生错误", fmt.Sprintf("订单号转换失败,错误信息:%s", err.Error()))
|
|
return 0, 0, 0, "", err
|
|
}
|
|
|
|
if result.TxnAmt != "" {
|
|
amountFloat, err := strconv.ParseFloat(result.TxnAmt, 64)
|
|
if err == nil {
|
|
amountTotal = int64(amountFloat * 100)
|
|
payerTotal = amountTotal
|
|
}
|
|
}
|
|
|
|
orderSta := ""
|
|
if result.OrderSta != "" {
|
|
orderSta = result.OrderSta
|
|
}
|
|
|
|
switch orderSta {
|
|
case "03":
|
|
status = "SUCCESS"
|
|
case "04", "05":
|
|
status = "FAIL"
|
|
default:
|
|
status = "NOTPAY"
|
|
}
|
|
|
|
return orderId, amountTotal, payerTotal, status, nil
|
|
}
|