pay

package
v0.0.0-...-245a666 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 12, 2019 License: MIT Imports: 24 Imported by: 0

README

Wechat pay API Wrapper for GO

支付方式

微信支付开发文档

微信网页支付 (JS-API)

微信网页支付流程

APP 支付

APP 支付流程

扫码支付

微信扫码支付流程

Documentation

Overview

https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=4_3

Index

Constants

View Source
const (
	NonceLength = 32
)

Variables

This section is empty.

Functions

func SetCertificationFile

func SetCertificationFile(cert, key string) error

SetCertificationFile initializes tls certification with: application_cert.pem & application_key.pem. should be called in the begining. see https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=4_3

Types

type AppPayRequest

type AppPayRequest struct {
	AppID     string `json:"appid,omitempty"`
	PartnerID string `json:"partnerid,omitempty"` // merchantID
	PrePayID  string `json:"prepayid,omitempty"`
	Package   string `json:"package,omitempty"`
	Nonce     string `json:"noncestr,omitempty"`
	TimeStamp string `json:"timestamp,omitempty"`
	Sign      string `json:"sign,omitempty"`
}

type BankType

type BankType string

type Bill

type Bill struct {
	// common fields for all type of bills
	Time          time.Time
	AppID         string
	MerchantID    string
	SubMerchantID string
	DeviceInfo    string
	TransactionID string
	TradeNo       string
	OpenID        string // 用户标识?
	TradeType
	TradeState
	BankType
	FeeType
	TotalFee  Fee
	CouponFee Fee

	ProductName   string
	Attach        string // 用户数据包
	ServiceCharge Fee    // 手续费
	ChargeRate    string // 费率

	// all bills for refund bills
	RefundID        string
	RefundNo        string
	RefundFee       Fee
	CouponRefundFee Fee
	RefundType      string
	RefundStatus

	// refund bills
	RefundApplyTime   time.Time
	RefundSucceedTime time.Time
}

type BillInTotal

type BillInTotal struct {
	Transactions    int
	TradeFee        Fee
	RefundFee       Fee
	CouponRefundFee Fee
	Charge          Fee
}

type BillType

type BillType string
const (
	BillAll     BillType = "ALL"
	BillSuccess BillType = "SUCCESS"
	BillRefund  BillType = "REFUND"
)

type CData

type CData struct {
	Data string `xml:",cdata"`
}

func (CData) String

func (cd CData) String() string

func (*CData) UnmarshalXML

func (cd *CData) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error

func (*CData) Unstring

func (cd *CData) Unstring(s string) error

type CloseOrderRequest

type CloseOrderRequest struct {
	TradeNo string `xml:"out_trade_no,omitempty"` // 商户订单号
}

type CouponType

type CouponType string
const (
	CouponCash   CouponType = "CASH"
	CouponNoCash CouponType = "NO_CASH"
)

type Date

type Date time.Time

func (Date) MarshalXML

func (d Date) MarshalXML(e *xml.Encoder, start xml.StartElement) error

func (Date) String

func (d Date) String() string

func (*Date) UnmarshalXML

func (d *Date) UnmarshalXML(dc *xml.Decoder, start xml.StartElement) error

func (*Date) Unstring

func (d *Date) Unstring(s string) error

type DownloadBillRequest

type DownloadBillRequest struct {
	DeviceInfo string `xml:"device_info,omitempty"`
	BillData   Date   `xml:"bill_data,omitempty"`
	BillType   `xml:"bill_type,omitempty"`
	TarType    `xml:"tar_type,omitempty"`
}

type ErrorCode

type ErrorCode string
const (
	SystemError ErrorCode = "SYSTEMERROR"
)

type Fee

type Fee int64

func (Fee) String

func (f Fee) String() string

func (*Fee) UnmarshalXML

func (f *Fee) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error

func (*Fee) Unstring

func (f *Fee) Unstring(s string) error

type FeeType

type FeeType string
const (
	CNY FeeType = "CNY"
)

type JSPayRequest

type JSPayRequest struct {
	AppID     string `json:"appId,omitempty"`
	TimeStamp string `json:"timeStamp,omitempty"`
	Nonce     string `json:"nonceStr,omitempty"`
	Package   string `json:"package,omitempty"`
	SignType  `json:"signType,omitempty"`
	PaySign   string `json:"paySign,omitempty"`
}

type LimitPay

type LimitPay string
const (
	NoCredit LimitPay = "no_credit"
)

type MerchantInfo

type MerchantInfo struct {
	AppID           string
	MerchantID      string
	PaymentKey      string
	PayNotifyURL    string
	RefundNotifyURL string
	PayNoticeHander
	RefundNoticeHandler
}

func (*MerchantInfo) CloseOrder

func (m *MerchantInfo) CloseOrder(req *CloseOrderRequest) error

func (*MerchantInfo) DownloadBill

func (m *MerchantInfo) DownloadBill(req *DownloadBillRequest) ([]*Bill, *BillInTotal, error)

func (*MerchantInfo) PayNotice

func (m *MerchantInfo) PayNotice(w http.ResponseWriter, r *http.Request)

func (*MerchantInfo) PrepareQRPay

func (m *MerchantInfo) PrepareQRPay(req *PreOrderRequest) (codeURL string, e error)

func (*MerchantInfo) QueryOrder

func (m *MerchantInfo) QueryOrder(req *QueryOrderRequest) (*QueryOrderResponse, error)

func (*MerchantInfo) QueryRefund

func (m *MerchantInfo) QueryRefund(req *QueryRefundRequest) (*QueryRefundResponse, error)

func (*MerchantInfo) RefundNotice

func (m *MerchantInfo) RefundNotice(w http.ResponseWriter, r *http.Request)

func (*MerchantInfo) RefundOrder

func (m *MerchantInfo) RefundOrder(req *RefundRequest) (*RefundResponse, error)

type NoticeResult

type NoticeResult struct {
	ReturnCode    CData `xml:"return_code,omitempty"`
	ReturnMessage CData `xml:"return_msg,omitempty"`
}

type PayNotice

type PayNotice struct {
	TradeState
	ResultCode     CData     `xml:"result_code,omitempty"`
	ResultMessage  CData     `xml:"result_msg,omitempty"`
	DeviceInfo     CData     `xml:"device_info,omitempty"`  // 设备号
	OpenID         CData     `xml:"openid,omitempty"`       // 用户标识
	IsSubscribe    CData     `xml:"is_subscribe,omitempty"` // 是否关注公众账号
	TradeType      TradeType `xml:"trade_type,omitempty"`
	BankType       BankType  `xml:"bank_type,omitempty"`            // 付款银行
	TotalFee       Fee       `xml:"total_fee,omitempty"`            // 标价金额
	SettlementFee  Fee       `xml:"settlement_total_fee,omitempty"` // 应结订单金额, 当订单使用了免充值型优惠券后返回该参数,应结订单金额=订单金额-免充值优惠券金额。
	FeeType        FeeType   `xml:"fee_type,omitempty"`
	CashFee        Fee       `xml:"cash_fee,omitempty"` // 现金支付金额
	CashFeeType    FeeType   `xml:"cash_fee_type,omitempty"`
	CouponFee      Fee       `xml:"coupon_fee,omitempty"`     // 代金券金额
	CouponCount    int       `xml:"coupon_count,omitempty"`   // 代金券使用数量
	CouponTypes    []CData   `xml:"coupon_type,omitempty"`    // 代金券类型
	CouponIDs      []CData   `xml:"coupon_id,omitempty"`      // 代金券ID
	CouponFees     []CData   `xml:"coupon_fee,omitempty"`     // 单个代金券支付金额
	TransactionID  CData     `xml:"transaction_id,omitempty"` // 微信支付订单号
	TradeNo        CData     `xml:"out_trade_no,omitempty"`   // 商户订单号
	Attach         CData     `xml:"attach,omitempty"`         // 附加数据
	TimeEnd        Time      `xml:"time_end,omitempty"`
	TradeStateDesc CData     `xml:"trade_state_desc,omitempty"`
}

type PayNoticeHander

type PayNoticeHander interface {
	HandlePayNotice(*PayNotice) error
}

https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_7 注意:同样的通知可能会多次发送给商户系统。商户系统必须能够正确处理重复的通知。 推荐的做法是,当收到通知进行处理时,首先检查对应业务数据的状态,判断该通知是否已经处理过, 如果没有处理过再进行处理,如果处理过直接返回结果成功。 在对业务数据进行状态检查和处理之前,要采用数据锁进行并发控制,以避免函数重入造成的数据混乱。 特别提醒:商户系统对于支付结果通知的内容一定要做签名验证,并校验返回的订单金额是否与商户侧的订单金额一致, 防止数据泄漏导致出现“假通知”,造成资金损失。

type PreOrderRequest

type PreOrderRequest struct {
	DeviceInfo  string     `xml:"device_info,omitempty"`      // 设备号
	Description string     `xml:"body,omitempty"`             // 商品描述 https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=4_2
	Detail      string     `xml:"detail,CDATA,omitempty"`     // 商品详情https://pay.weixin.qq.com/wiki/doc/api/danpin.php?chapter=9_102&index=2
	Attach      string     `xml:"attach,omitempty"`           // 附加数据
	TradeNo     string     `xml:"out_trade_no,omitempty"`     // 商户系统内部订单号,要求32个字符内,只能是数字、大小写字母_-|*@ ,且在同一个商户号下唯一
	FeeType     FeeType    `xml:"fee_type,omitempty"`         // 符合ISO 4217标准的三位字母代码,默认人民币:CNY
	TotalFee    Fee        `xml:"total_fee,omitempty"`        // 标价金额, 订单总金额,单位为分
	CreateIP    string     `xml:"spbill_create_ip,omitempty"` // APP和网页支付提交用户端ip,Native支付填调用微信支付API的机器IP
	TimeStart   Time       `xml:"time_start,omitempty"`       // yyyyMMddHHmmss
	TimeExpire  Time       `xml:"time_expire,omitempty"`      // yyyyMMddHHmmss 最短失效时间间隔必须大于5分钟
	GoodsTag    string     `xml:"goods_tag,omitempty"`        // https://pay.weixin.qq.com/wiki/doc/api/tools/sp_coupon.php?chapter=12_1
	NotifyURL   string     `xml:"notify_url,omitempty"`       // 异步接收微信支付结果通知的回调地址,通知url必须为外网可访问的url,不能携带参数。
	TradeType   TradeType  `xml:"trade_type,omitempty"`       // 交易类型 取值如下:JSAPI,NATIVE,APP
	ProductID   string     `xml:"product_id,omitempty"`       // 扫码支付必填 此参数为二维码中包含的商品ID,商户自行定义。
	LimitPay    LimitPay   `xml:"limit_pay,omitempty"`        // 上传此参数no_credit--可限制用户不能使用信用卡支付
	OpenID      string     `xml:"openid,omitempty"`           // 公众号支付必填
	SceneInfo   *SceneInfo `xml:"scene_info,omitempty"`       // 上报场景信息,目前支持上报实际门店信息。该字段为JSON对象数据
}

type PreOrderResponse

type PreOrderResponse struct {
	DeviceInfo CData `xml:"deviceInfo,omitempty"`
	TradeType  `xml:"trade_type,omitempty"`
	PrepayID   CData `xml:"prepay_id,omitempty"`
	CodeURL    CData `xml:"code_url,omitempty"`
	WebURL     CData `xml:"mweb_url,omitemtpy"` // mweb_url为拉起微信支付收银台的中间页面,可通过访问该url来拉起微信客户端,完成支付,mweb_url的有效期为5分钟。
}

type QueryOrderRequest

type QueryOrderRequest struct {
	TransactionID string `xml:"transaction_id,omitempty"` // 商户订单号 二选一
	TradeNo       string `xml:"out_trade_no,omitempty"`   // 微信的订单号,建议优先使用
}

type QueryOrderResponse

type QueryOrderResponse struct {
	DeviceInfo     CData      `xml:"device_info,omitempty"`  // 设备号
	OpenID         CData      `xml:"openid,omitempty"`       // 用户标识
	IsSubscribe    CData      `xml:"is_subscribe,omitempty"` // 是否关注公众账号
	TradeType      TradeType  `xml:"trade_type,omitempty"`
	TradeStatus    TradeState `xml:"trade_state,omitempty"`
	BankType       BankType   `xml:"bank_type,omitempty"`            // 付款银行
	TotalFee       Fee        `xml:"total_fee,omitempty"`            // 标价金额
	SettlementFee  Fee        `xml:"settlement_total_fee,omitempty"` // 应结订单金额, 当订单使用了免充值型优惠券后返回该参数,应结订单金额=订单金额-免充值优惠券金额。
	FeeType        FeeType    `xml:"fee_type,omitempty"`
	CashFee        Fee        `xml:"cash_fee,omitempty"` // 现金支付金额
	CashFeeType    FeeType    `xml:"cash_fee_type,omitempty"`
	CouponFee      Fee        `xml:"coupon_fee,omitempty"`     // 代金券金额
	CouponCount    int        `xml:"coupon_count,omitempty"`   // 代金券使用数量
	CouponTypes    []CData    `xml:"coupon_type,omitempty"`    // 代金券类型
	CouponIDs      []CData    `xml:"coupon_id,omitempty"`      // 代金券ID
	CouponFees     []CData    `xml:"coupon_fee,omitempty"`     // 单个代金券支付金额
	TransactionID  CData      `xml:"transaction_id,omitempty"` // 微信支付订单号
	TradeNo        CData      `xml:"out_trade_no,omitempty"`   // 商户订单号
	Attach         CData      `xml:"attach,omitempty"`         // 附加数据
	TimeEnd        Time       `xml:"time_end,omitempty"`
	TradeStateDesc CData      `xml:"trade_state_desc,omitempty"`
}

type QueryRefundRequest

type QueryRefundRequest struct {
	TransactionID string `xml:"transaction_id,omitempty"` // 微信订单号
	TradeNo       string `xml:"out_trade_no,omitempty"`   // 商户订单号
	RefundNo      string `xml:"out_refund_no,omitempty"`  // 商户退款单号
	RefundID      string `xml:"refund_id,omitempty"`      // 微信退款单号
}

四选一 refund_id > refund_no > transaction_id > trade_no

type QueryRefundResponse

type QueryRefundResponse struct {
	TransactionID          CData          `xml:"transaction_id,omitempty"`       // 微信订单号
	TradeNo                CData          `xml:"out_trade_no,omitempty"`         // 商户订单号
	TotalFee               Fee            `xml:"total_fee,omitempty"`            // 订单金额
	SettlementFee          Fee            `xml:"settlement_total_fee,omitempty"` // 应结订单金额, 去掉非充值代金券金额后的订单总金额,应结订单金额=订单金额-非充值代金券金额,应结订单金额<=订单金额。
	FeeType                FeeType        `xml:"fee_type,omitempty"`
	CashFee                Fee            `xml:"cash_fee,omitempty"`              // 现金支付金额
	RefundCount            int            `xml:"refund_count,omitempty"`          // 退款笔数
	RefundNos              []CData        `xml:"out_refund_no,omitempty"`         // 商户退款单号
	RefundIDs              []CData        `xml:"refund_id,omitempty"`             // 微信退款单号
	RefundChannels         []CData        `xml:"refund_channel,omitempty"`        // 退款渠道
	RefundFees             []Fee          `xml:"refund_fee,omitempty"`            // 申请退款金额
	SettlementRefundFees   []Fee          `xml:"settlement_refund_fee,omitempty"` // 退款金额
	CouponRefundFees       []Fee          `xml:"coupon_refund_fee,omitempty"`     // 总代金券退款金额, 代金券退款金额<=退款金额,退款金额-代金券或立减优惠退款金额为现金
	CouponRefundCount      []Fee          `xml:"coupon_refund_count,omitempty"`   // 退款代金券使用数量
	RefundStatus           []RefundStatus `xml:"refund_status,omitempty"`
	RefundAccounts         []CData        `xml:"refund_account,omitempty"`      // 退款资金来源
	RefundReceiverAccounts []CData        `xml:"refund_recv_account,omitempty"` // 退款入账账户
	RefundSuccessTime      []Time         `xml:"refund_success_time,omitempty"`
}

not include coupon_type, coupon_refund_fee, coupon_refund_id

type RefundNotice

type RefundNotice struct {
	ResultCode            CData        `xml:"result_code,omitempty"`
	ResultMessage         CData        `xml:"result_msg,omitempty"`
	TransactionID         CData        `xml:"transaction_id,omitempty"`        // 微信订单号
	TradeNo               CData        `xml:"out_trade_no,omitempty"`          // 商户订单号
	RefundNo              CData        `xml:"out_refund_no,omitempty"`         // 商户退款单号
	RefundID              CData        `xml:"refund_id,omitempty"`             // 微信退款单号
	TotalFee              Fee          `xml:"total_fee,omitempty"`             // 订单金额
	SettlementFee         Fee          `xml:"settlement_total_fee,omitempty"`  // 应结订单金额, 去掉非充值代金券金额后的订单总金额,应结订单金额=订单金额-非充值代金券金额,应结订单金额<=订单金额。
	RefundFees            Fee          `xml:"refund_fee,omitempty"`            // 申请退款金额
	SettlementRefundFees  Fee          `xml:"settlement_refund_fee,omitempty"` // 退款金额
	RefundStatus          RefundStatus `xml:"refund_status,omitempty"`
	SuccessTime           Time         `xml:"success_time,omitempty"`
	RefundReceiverAccount CData        `xml:"refund_recv_account,omitempty"` // 退款入账账户
	RefundAccount         CData        `xml:"refund_account,omitempty"`      // 退款资金来源
	RefundRequestSource   string       `xml:"refund_request_source,omitempty"`
}

type RefundNoticeHandler

type RefundNoticeHandler interface {
	HandleRefundNotice(*RefundNotice) error
}

https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_16&index=9 注意:同样的通知可能会多次发送给商户系统。商户系统必须能够正确处理重复的通知。 推荐的做法是,当收到通知进行处理时,首先检查对应业务数据的状态,判断该通知是否已经处理过, 如果没有处理过再进行处理,如果处理过直接返回结果成功。 在对业务数据进行状态检查和处理之前,要采用数据锁进行并发控制,以避免函数重入造成的数据混乱。

type RefundRequest

type RefundRequest struct {
	TransactionID string  `xml:"transaction_id,omitempty"` // 微信订单号, 与 TradeNo 二选一
	TradeNo       string  `xml:"out_trade_no,omitempty"`   // 商户系统内部订单号, 与 TransactionID 二选一
	RefundNo      string  `xml:"out_refund_no,omitempty"`  // 商户系统内部的退款单号
	TotalFee      Fee     `xml:"total_fee,omitempty"`      // 订单金额
	RefundFee     Fee     `xml:"refund_fee,omitempty"`     // 退款金额
	RefundFeeType FeeType `xml:"refund_fee_type,omitempty"`
	RefundDesc    string  `xml:"refund_desc,omitempty"`
	RefundAccount string  `xml:"refund_account,omitempty"` // 退款资金来源
}

type RefundResponse

type RefundResponse struct {
	TransactionID       CData   `xml:"transaction_id,omitempty"`        // 微信订单号
	TradeNo             CData   `xml:"out_trade_no,omitempty"`          // 商户订单号
	RefundNo            CData   `xml:"out_refund_no,omitempty"`         // 商户退款单号
	RefundID            CData   `xml:"refund_id,omitempty"`             // 微信退款单号
	RefundFee           Fee     `xml:"refund_fee,omitempty"`            // 退款总金额,单位为分,可以做部分退款
	SettlementRefundFee Fee     `xml:"settlement_refund_fee,omitempty"` // 应结退款金额, 去掉非充值代金券退款金额后的退款金额,退款金额=申请退款金额-非充值代金券退款金额,退款金额<=申请退款金额应结退款金额
	TotalFee            Fee     `xml:"total_fee,omitempty"`             // 标价金额
	SettlementTotalFee  Fee     `xml:"settlement_total_fee,omitempty"`  // 应结订单金额, 去掉非充值代金券金额后的订单总金额,应结订单金额=订单金额-非充值代金券金额,应结订单金额<=订单金额。
	RefundFeeType       FeeType `xml:"refund_fee_type,omitempty"`
	FeeType             FeeType `xml:"fee_type,omitempty"`
	CashFee             Fee     `xml:"cash_fee,omitempty"` // 现金支付金额
	CashFeeType         FeeType `xml:"cash_fee_type,omitempty"`
	CashRefundFee       Fee     `xml:"cash_refund_fee,omitempty"`   // 现金退款金额
	CouponRefundFee     Fee     `xml:"coupon_refund_fee,omitempty"` // 代金券退款总金额
	CouponRefundFees    []Fee   `xml:"coupon_refund_fee,omitempty"` // 单个代金券退款金额
	CouponRefundIDs     []CData `xml:"coupon_refund_id,omitempty"`  // 退款代金券ID
	CouponRefundCount   int     `xml:"coupon_refund_count,omitempty"`
}

type RefundStatus

type RefundStatus string
const (
	RefundProcessing RefundStatus = "PROCESSING"
	RefundSuccess    RefundStatus = "SUCCESS"
	RefundClosed     RefundStatus = "REFUNDCLOSE"
	RefundChanged    RefundStatus = "CHANGE"
)

type ResponseBase

type ResponseBase struct {
	XMLName          xml.Name `xml:"xml"`
	ReturnCode       CData    `xml:"return_code,omitempty"`
	ReturnMessage    CData    `xml:"return_msg,omitempty"`
	AppID            CData    `xml:"appid,omitempty"`
	MerchantID       CData    `xml:"mch_id,omitempty"`
	Nonce            CData    `xml:"nonce_str,omitempty"`
	Sign             CData    `xml:"sign,omitempty"`
	ResultCode       CData    `xml:"result_code,omitempty"`
	ResultMessage    CData    `xml:"result_msg,omitempty"`
	ErrorCode        CData    `xml:"err_code,omitempty"`
	ErrorDescription CData    `xml:"err_code_des,omitempty"`
}

type SceneInfo

type SceneInfo struct {
	ID       string `json:"id,omitempty"`        // 门店唯一标识
	Name     string `json:"name,omitempty"`      // 门店名称
	AreaCode string `json:"area_code,omitempty"` // 门店所在地行政区划码
	Address  string `json:"address,omitempty"`   // 门店详细地址
}

func (*SceneInfo) MarshalXML

func (si *SceneInfo) MarshalXML(e *xml.Encoder, start xml.StartElement) error

func (*SceneInfo) String

func (si *SceneInfo) String() string

func (*SceneInfo) Unstring

func (si *SceneInfo) Unstring(s string) error

type SignType

type SignType string
const (
	MD5  SignType = "MD5"
	HMAC SignType = "HMAC-SHA256"
)

type TarType

type TarType string
const (
	GZIP TarType = "GZIP"
)

type Time

type Time time.Time

func (Time) MarshalXML

func (t Time) MarshalXML(e *xml.Encoder, start xml.StartElement) error

func (Time) String

func (t Time) String() string

func (*Time) UnmarshalXML

func (t *Time) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error

func (*Time) Unstring

func (t *Time) Unstring(s string) error

type TradeState

type TradeState string
const (
	NotPay     TradeState = "NOTPAY"
	PaySuccess TradeState = "SUCCESS"
	PayRefund  TradeState = "REFUND"
	PayClosed  TradeState = "CLOSED"
	PayError   TradeState = "PAYERROR"
	PayRevoked TradeState = "REVOKED"
	Paying     TradeState = "USERPAYING"
)

type TradeType

type TradeType string
const (
	JSAPIPay TradeType = "JSAPI"  // 公众号支付
	QRPay    TradeType = "NATIVE" // 扫码支付
	AppPay   TradeType = "APP"    // APP 支付
	WebPay   TradeType = "MWEB"   // H5 支付
)

type Unstringer

type Unstringer interface {
	Unstring(string) error
}

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL