service/vendor/github.com/go-pay/gopay/wechat/base_api.go

218 lines
7.3 KiB
Go
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.

package wechat
import (
"context"
"crypto/tls"
"encoding/xml"
"errors"
"fmt"
"github.com/go-pay/gopay"
"github.com/go-pay/gopay/pkg/util"
)
// 统一下单
// 商户文档https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_1
// 服务商文档https://pay.weixin.qq.com/wiki/doc/api/jsapi_sl.php?chapter=9_1
func (w *Client) UnifiedOrder(ctx context.Context, bm gopay.BodyMap) (wxRsp *UnifiedOrderResponse, err error) {
err = bm.CheckEmptyError("nonce_str", "body", "out_trade_no", "total_fee", "spbill_create_ip", "notify_url", "trade_type")
if err != nil {
return nil, err
}
var bs []byte
if w.IsProd {
bs, err = w.doProdPost(ctx, bm, unifiedOrder, nil)
} else {
bm.Set("total_fee", 101)
bs, err = w.doSanBoxPost(ctx, bm, sandboxUnifiedOrder)
}
if err != nil {
return nil, err
}
wxRsp = new(UnifiedOrderResponse)
if err = xml.Unmarshal(bs, wxRsp); err != nil {
return nil, fmt.Errorf("[%w]: %v, bytes: %s", gopay.UnmarshalErr, err, string(bs))
}
return wxRsp, nil
}
// 提交付款码支付
// 商户文档https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=9_10&index=1
// 服务商文档https://pay.weixin.qq.com/wiki/doc/api/micropay_sl.php?chapter=9_10&index=1
func (w *Client) Micropay(ctx context.Context, bm gopay.BodyMap) (wxRsp *MicropayResponse, err error) {
err = bm.CheckEmptyError("nonce_str", "body", "out_trade_no", "total_fee", "spbill_create_ip", "auth_code")
if err != nil {
return nil, err
}
var bs []byte
if w.IsProd {
bs, err = w.doProdPost(ctx, bm, microPay, nil)
} else {
bm.Set("total_fee", 1)
bs, err = w.doSanBoxPost(ctx, bm, sandboxMicroPay)
}
if err != nil {
return nil, err
}
wxRsp = new(MicropayResponse)
if err = xml.Unmarshal(bs, wxRsp); err != nil {
return nil, fmt.Errorf("[%w]: %v, bytes: %s", gopay.UnmarshalErr, err, string(bs))
}
return wxRsp, nil
}
// 查询订单
// 商户文档https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_2
// 服务商文档https://pay.weixin.qq.com/wiki/doc/api/jsapi_sl.php?chapter=9_2
func (w *Client) QueryOrder(ctx context.Context, bm gopay.BodyMap) (wxRsp *QueryOrderResponse, resBm gopay.BodyMap, err error) {
err = bm.CheckEmptyError("nonce_str")
if err != nil {
return nil, nil, err
}
if bm.GetString("out_trade_no") == util.NULL && bm.GetString("transaction_id") == util.NULL {
return nil, nil, errors.New("out_trade_no and transaction_id are not allowed to be null at the same time")
}
var bs []byte
if w.IsProd {
bs, err = w.doProdPost(ctx, bm, orderQuery, nil)
} else {
bs, err = w.doSanBoxPost(ctx, bm, sandboxOrderQuery)
}
if err != nil {
return nil, nil, err
}
wxRsp = new(QueryOrderResponse)
if err = xml.Unmarshal(bs, wxRsp); err != nil {
return nil, nil, fmt.Errorf("xml.UnmarshalStruct(%s)%w", string(bs), err)
}
resBm = make(gopay.BodyMap)
if err = xml.Unmarshal(bs, &resBm); err != nil {
return nil, nil, fmt.Errorf("xml.UnmarshalBodyMap(%s)%w", string(bs), err)
}
return wxRsp, resBm, nil
}
// 关闭订单
// 商户文档https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_3
// 服务商文档https://pay.weixin.qq.com/wiki/doc/api/jsapi_sl.php?chapter=9_3
func (w *Client) CloseOrder(ctx context.Context, bm gopay.BodyMap) (wxRsp *CloseOrderResponse, err error) {
err = bm.CheckEmptyError("nonce_str", "out_trade_no")
if err != nil {
return nil, err
}
var bs []byte
if w.IsProd {
bs, err = w.doProdPost(ctx, bm, closeOrder, nil)
} else {
bs, err = w.doSanBoxPost(ctx, bm, sandboxCloseOrder)
}
if err != nil {
return nil, err
}
wxRsp = new(CloseOrderResponse)
if err = xml.Unmarshal(bs, wxRsp); err != nil {
return nil, fmt.Errorf("[%w]: %v, bytes: %s", gopay.UnmarshalErr, err, string(bs))
}
return wxRsp, nil
}
// 申请退款
// 注意请在初始化client时调用 client 添加证书的相关方法添加证书
// 商户文档https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_4
// 服务商文档https://pay.weixin.qq.com/wiki/doc/api/jsapi_sl.php?chapter=9_4
func (w *Client) Refund(ctx context.Context, bm gopay.BodyMap) (wxRsp *RefundResponse, resBm gopay.BodyMap, err error) {
err = bm.CheckEmptyError("nonce_str", "out_refund_no", "total_fee", "refund_fee")
if err != nil {
return nil, nil, err
}
if bm.GetString("out_trade_no") == util.NULL && bm.GetString("transaction_id") == util.NULL {
return nil, nil, errors.New("out_trade_no and transaction_id are not allowed to be null at the same time")
}
var (
bs []byte
tlsConfig *tls.Config
)
if w.IsProd {
if tlsConfig, err = w.addCertConfig(nil, nil, nil); err != nil {
return nil, nil, err
}
bs, err = w.doProdPost(ctx, bm, refund, tlsConfig)
} else {
bs, err = w.doSanBoxPost(ctx, bm, sandboxRefund)
}
if err != nil {
return nil, nil, err
}
wxRsp = new(RefundResponse)
if err = xml.Unmarshal(bs, wxRsp); err != nil {
return nil, nil, fmt.Errorf("xml.UnmarshalStruct(%s)%w", string(bs), err)
}
resBm = make(gopay.BodyMap)
if err = xml.Unmarshal(bs, &resBm); err != nil {
return nil, nil, fmt.Errorf("xml.UnmarshalBodyMap(%s)%w", string(bs), err)
}
return wxRsp, resBm, nil
}
// 查询退款
// 商户文档https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_5
// 服务商文档https://pay.weixin.qq.com/wiki/doc/api/jsapi_sl.php?chapter=9_5
func (w *Client) QueryRefund(ctx context.Context, bm gopay.BodyMap) (wxRsp *QueryRefundResponse, resBm gopay.BodyMap, err error) {
err = bm.CheckEmptyError("nonce_str")
if err != nil {
return nil, nil, err
}
if bm.GetString("refund_id") == util.NULL && bm.GetString("out_refund_no") == util.NULL && bm.GetString("transaction_id") == util.NULL && bm.GetString("out_trade_no") == util.NULL {
return nil, nil, errors.New("refund_id, out_refund_no, out_trade_no, transaction_id are not allowed to be null at the same time")
}
var bs []byte
if w.IsProd {
bs, err = w.doProdPost(ctx, bm, refundQuery, nil)
} else {
bs, err = w.doSanBoxPost(ctx, bm, sandboxRefundQuery)
}
if err != nil {
return nil, nil, err
}
wxRsp = new(QueryRefundResponse)
if err = xml.Unmarshal(bs, wxRsp); err != nil {
return nil, nil, fmt.Errorf("xml.UnmarshalStruct(%s)%w", string(bs), err)
}
resBm = make(gopay.BodyMap)
if err = xml.Unmarshal(bs, &resBm); err != nil {
return nil, nil, fmt.Errorf("xml.UnmarshalBodyMap(%s)%w", string(bs), err)
}
return wxRsp, resBm, nil
}
// 撤销订单
// 注意请在初始化client时调用 client 添加证书的相关方法添加证书
// 商户文档https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=9_11&index=3
// 服务商文档https://pay.weixin.qq.com/wiki/doc/api/micropay_sl.php?chapter=9_11&index=3
func (w *Client) Reverse(ctx context.Context, bm gopay.BodyMap) (wxRsp *ReverseResponse, err error) {
err = bm.CheckEmptyError("nonce_str", "out_trade_no")
if err != nil {
return nil, err
}
var (
bs []byte
tlsConfig *tls.Config
)
if w.IsProd {
if tlsConfig, err = w.addCertConfig(nil, nil, nil); err != nil {
return nil, err
}
bs, err = w.doProdPost(ctx, bm, reverse, tlsConfig)
} else {
bs, err = w.doSanBoxPost(ctx, bm, sandboxReverse)
}
if err != nil {
return nil, err
}
wxRsp = new(ReverseResponse)
if err = xml.Unmarshal(bs, wxRsp); err != nil {
return nil, fmt.Errorf("[%w]: %v, bytes: %s", gopay.UnmarshalErr, err, string(bs))
}
return wxRsp, nil
}