package paymentService import ( "PaymentCenter/app/third/paymentService/payCommon" psbc "PaymentCenter/app/third/paymentService/psbc" "PaymentCenter/config" "context" "errors" "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 } 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, } 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.CreatePaymentLink(req) if err != nil { logger.Error(c, "PsbcPayInfo 发生错误", fmt.Sprintf("错误信息:%s", err.Error())) return "", err } return resp.PayUrl, 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 = "未支付" } amountTotal := int64(0) payerTotal := int64(0) outTradeNo, _ := strconv.ParseInt(orderNo, 10, 64) return PayOrderQueryInfo{ AppId: psbcConfig.AppID, OutTradeNo: outTradeNo, TransactionId: "", TradeState: tradeState, TradeStateDesc: tradeStateDesc, 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 } orderNoStr := "" if orderNo, ok := result["orderNo"].(string); ok { orderNoStr = orderNo } if orderNoStr == "" { return 0, 0, 0, "", errors.New("回调数据中缺少订单号") } orderId, err = strconv.ParseInt(orderNoStr, 10, 64) if err != nil { logger.Error(context.Background(), "PsbcVerifyAndParseNotify 发生错误", fmt.Sprintf("订单号转换失败,错误信息:%s", err.Error())) return 0, 0, 0, "", err } amountStr := "" if amount, ok := result["amount"].(string); ok { amountStr = amount } if amountStr != "" { amountFloat, err := strconv.ParseFloat(amountStr, 64) if err == nil { amountTotal = int64(amountFloat * 100) payerTotal = amountTotal } } orderSta := "" if sta, ok := result["orderSta"].(string); ok { orderSta = sta } switch orderSta { case "03": status = "SUCCESS" case "04", "05": status = "FAIL" default: status = "NOTPAY" } return orderId, amountTotal, payerTotal, status, nil }