精华内容
下载资源
问答
  • Golang版本 微信支付、支付宝支付 SDK

    万次阅读 2019-01-16 13:09:42
    微信支付、支付宝支付等的Go版本SDK(持续更新维护中) 微信 统一下单 JSAPI - JSAPI支付(或小程序支付) NATIVE - Native支付 APP - app支付 MWEB - H5支付 查询订单(开发中) 关闭订单(开发中...
    Logo was Loading Faild!

    GoPay

    文档会更新,点击查看最新文档

    微信、QQ、支付宝的Golang版本SDK


    一、安装

    $ go get github.com/go-pay/gopay
    
    import (
        "fmt"
    
        "github.com/go-pay/gopay"
        "github.com/go-pay/gopay/pkg/xlog"
    )
    
    func main() {
        xlog.Debug("GoPay Version: ", gopay.Version)
    }
    

    微信支付V3 API

    推荐使用V3接口,官方在V3接口实现未覆盖或gopay未开发的接口,还继续用V2接口,欢迎参与完善V3接口。

    • 基础支付(直连模式)
      • APP下单:client.V3TransactionApp()
      • JSAPI/小程序下单:client.V3TransactionJsapi()
      • Native下单:client.V3TransactionNative()
      • H5下单:client.V3TransactionH5()
      • 查询订单:client.V3TransactionQueryOrder()
      • 关闭订单:client.V3TransactionCloseOrder()
    • 基础支付(服务商模式)
      • APP下单:client.V3PartnerTransactionApp()
      • JSAPI/小程序下单:client.V3PartnerTransactionJsapi()
      • Native下单:client.V3PartnerTransactionNative()
      • H5下单:client.V3PartnerTransactionH5()
      • 查询订单:client.V3PartnerQueryOrder()
      • 关闭订单:client.V3PartnerCloseOrder()
    • 合单支付
      • 合单APP下单:client.V3CombineTransactionApp()
      • 合单JSAPI/小程序下单:client.V3CombineTransactionJsapi()
      • 合单Native下单:client.V3CombineTransactionNative()
      • 合单H5下单:client.V3CombineTransactionH5()
      • 合单查询订单:client.V3CombineQueryOrder()
      • 合单关闭订单:client.V3CombineCloseOrder()
    • 退款
      • 申请退款:client.V3Refund()
      • 查询单笔退款:client.V3RefundQuery()
    • 账单
      • 申请交易账单:client.V3BillTradeBill()
      • 申请资金账单:client.V3BillFundFlowBill()
      • 申请二级商户资金账单:client.V3BillLevel2FundFlowBill()
      • 下载账单:client.V3BillDownLoadBill()
    • 微信支付分(公共API)
      • 创建支付分订单:client.V3ScoreOrderCreate()
      • 查询支付分订单:client.V3ScoreOrderQuery()
      • 取消支付分订单:client.V3ScoreOrderCancel()
      • 修改订单金额:client.V3ScoreOrderModify()
      • 完结支付分订单:client.V3ScoreOrderComplete()
      • 商户发起催收扣款:client.V3ScoreOrderPay()
      • 同步服务订单信息:client.V3ScoreOrderSync()
    • 微信支付分(免确认模式)
      • 创单结单合并:client.V3ScoreDirectComplete()
    • 微信支付分(免确认预授权模式)
      • 商户预授权:client.V3ScorePermission()
      • 查询用户授权记录(授权协议号):client.V3ScorePermissionQuery()
      • 解除用户授权关系(授权协议号):client.V3ScorePermissionTerminate()
      • 查询用户授权记录(openid):client.V3ScorePermissionOpenidQuery()
      • 解除用户授权关系(openid):client.V3ScorePermissionOpenidTerminate()
    • 微信先享卡
      • 待实现
    • 支付即服务
      • 待实现
    • 智慧商圈
      • 待实现
    • 代金券
      • 待实现
    • 商家券
      • 待实现
    • 委托营销
      • 待实现
    • 消费卡
      • 待实现
    • 支付有礼
      • 待实现
    • 分账
      • 请求分账:client.V3ProfitShareOrder()
      • 查询分账结果:client.V3ProfitShareOrderQuery()
      • 请求分账回退:client.V3ProfitShareReturn()
      • 查询分账回退结果:client.V3ProfitShareReturnResult()
      • 解冻剩余资金:client.V3ProfitShareOrderUnfreeze()
      • 查询剩余待分金额:client.V3ProfitShareUnsplitAmount()
      • 添加分账接收方:client.V3ProfitShareAddReceiver()
      • 删除分账接收方:client.V3ProfitShareDeleteReceiver()
    • 消费者投诉2.0
      • 查询投诉单列表:client.V3ComplaintList()
      • 查询投诉单详情:client.V3ComplaintDetail()
      • 查询投诉协商历史:client.V3ComplaintNegotiationHistory()
      • 创建投诉通知回调地址:client.V3ComplaintNotifyUrlCreate()
      • 查询投诉通知回调地址:client.V3ComplaintNotifyUrlQuery()
      • 更新投诉通知回调地址:client.V3ComplaintNotifyUrlUpdate()
      • 删除投诉通知回调地址:client.V3ComplaintNotifyUrlDelete()
      • 提交回复:client.V3ComplaintResponse()
      • 反馈处理完成:client.V3ComplaintComplete()
      • 商户上传反馈图片:client.V3ComplaintUploadImage()
    • 其他能力
      • 图片上传:client.V3MediaUploadImage()
      • 视频上传:client.V3MediaUploadVideo()

    微信支付V2 API

    推荐使用V3接口,官方在V3接口实现未覆盖或gopay未开发的接口,还继续用V2接口。

    • 统一下单:client.UnifiedOrder()
      • JSAPI - JSAPI支付(或小程序支付)
      • NATIVE - Native支付
      • APP - app支付
      • MWEB - H5支付
    • 提交付款码支付:client.Micropay()
    • 查询订单:client.QueryOrder()
    • 关闭订单:client.CloseOrder()
    • 撤销订单:client.Reverse()
    • 申请退款:client.Refund()
    • 查询退款:client.QueryRefund()
    • 下载对账单:client.DownloadBill()
    • 下载资金账单(正式):client.DownloadFundFlow()
    • 交易保障:client.Report()
    • 拉取订单评价数据(正式):client.BatchQueryComment()
    • 企业付款(正式):client.Transfer()
    • 查询企业付款(正式):client.GetTransferInfo()
    • 授权码查询OpenId(正式):client.AuthCodeToOpenId()
    • 公众号纯签约(正式):client.EntrustPublic()
    • APP纯签约-预签约接口-获取预签约ID(正式):client.EntrustAppPre()
    • H5纯签约(正式):client.EntrustH5()
    • 支付中签约(正式):client.EntrustPaying()
    • 请求单次分账(正式):client.ProfitSharing()
    • 请求多次分账(正式):client.MultiProfitSharing()
    • 查询分账结果(正式):client.ProfitSharingQuery()
    • 添加分账接收方(正式):client.ProfitSharingAddReceiver()
    • 删除分账接收方(正式):client.ProfitSharingRemoveReceiver()
    • 完结分账(正式):client.ProfitSharingFinish()
    • 分账回退(正式):client.ProfitSharingReturn()
    • 分账回退结果查询(正式):client.ProfitSharingReturnQuery()
    • 企业付款到银行卡API(正式):client.PayBank()
    • 查询企业付款到银行卡API(正式):client.QueryBank()
    • 获取RSA加密公钥API(正式):client.GetRSAPublicKey()
    • 发放现金红包:client.SendCashRed()
    • 发放现金裂变红包:client.SendGroupCashRed()
    • 发放小程序红包:client.SendAppletRed()
    • 查询红包记录:client.QueryRedRecord()
    • 自定义方法请求微信API接口:client.PostWeChatAPISelf()

    微信公共V2 API

    • wechat.GetParamSign() => 获取微信支付所需参数里的Sign值(通过支付参数计算Sign值)
    • wechat.GetSanBoxParamSign() => 获取微信支付沙箱环境所需参数里的Sign值(通过支付参数计算Sign值)
    • wechat.GetMiniPaySign() => 获取微信小程序支付所需要的paySign
    • wechat.GetH5PaySign() => 获取微信内H5支付所需要的paySign
    • wechat.GetAppPaySign() => 获取APP支付所需要的paySign
    • wechat.ParseNotifyToBodyMap() => 解析微信支付异步通知的参数到BodyMap
    • wechat.ParseNotify() => 解析微信支付异步通知的参数
    • wechat.ParseRefundNotify() => 解析微信退款异步通知的参数
    • wechat.VerifySign() => 微信同步返回参数验签或异步通知参数验签
    • wechat.Code2Session() => 登录凭证校验:获取微信用户OpenId、UnionId、SessionKey
    • wechat.GetAppletAccessToken() => 获取微信小程序全局唯一后台接口调用凭据
    • wechat.GetAppletPaidUnionId() => 微信小程序用户支付完成后,获取该用户的 UnionId,无需用户授权
    • wechat.GetPublicUserInfo() => 微信公众号:获取用户基本信息
    • wechat.GetPublicUserInfoBatch() => 微信公众号:批量获取用户基本信息
    • wechat.DecryptOpenDataToStruct() => 加密数据,解密到指定结构体
    • wechat.DecryptOpenDataToBodyMap() => 加密数据,解密到 BodyMap
    • wechat.GetOpenIdByAuthCode() => 授权码查询openid
    • wechat.GetOauth2AccessToken() => 微信第三方登录,code 换取 access_token
    • wechat.RefreshOauth2AccessToken() => 刷新微信第三方登录后,获取到的 access_token
    • wechat.CheckOauth2AccessToken() => 检验授权凭证(access_token)是否有效
    • wechat.GetOauth2UserInfo() => 微信开放平台:获取用户个人信息
    • wechat.DecryptRefundNotifyReqInfo() => 解密微信退款异步通知的加密数据

    QQ支付API

    • 提交付款码支付:client.MicroPay()
    • 撤销订单:client.Reverse()
    • 统一下单:client.UnifiedOrder()
    • 订单查询:client.OrderQuery()
    • 关闭订单:client.CloseOrder()
    • 申请退款:client.Refund()
    • 退款查询:client.RefundQuery()
    • 交易账单:client.StatementDown()
    • 资金账单:client.AccRoll()
    • 创建现金红包(未测试可用性):client.SendCashRed()
    • 对账单下载(未测试可用性):client.DownloadRedListFile()
    • 查询红包详情(未测试可用性):client.QueryRedInfo()
    • 自定义方法请求微信API接口:client.PostQQAPISelf()

    QQ公共API

    • qq.ParseNotifyToBodyMap() => 解析QQ支付异步通知的结果到BodyMap
    • qq.ParseNotify() => 解析QQ支付异步通知的参数
    • qq.VerifySign() => QQ同步返回参数验签或异步通知参数验签

    支付宝支付API

    因支付宝接口太多,如没实现的接口,还请开发者自行调用client.PostAliPayAPISelfV2()方法实现!请参考 client_test.go 内的 TestClient_PostAliPayAPISelfV2() 方法

    希望有时间的伙伴儿Fork完后,积极提Pull Request,一起完善支付宝各个类别下的接口到相应的go文件中

    • 支付宝接口自行实现方法:client.PostAliPayAPISelfV2()
    • 网页&移动应用 - 支付API
      • 统一收单交易支付接口(商家扫用户付款码):client.TradePay()
      • 统一收单线下交易预创建(用户扫商品收款码):client.TradePrecreate()
      • APP支付接口2.0(APP支付):client.TradeAppPay()
      • 手机网站支付接口2.0(手机网站支付):client.TradeWapPay()
      • 统一收单下单并支付页面接口(电脑网站支付):client.TradePagePay()
      • 统一收单交易创建接口(小程序支付):client.TradeCreate()
      • 统一收单线下交易查询:client.TradeQuery()
      • 统一收单交易撤销接口:client.TradeCancel()
      • 统一收单交易关闭接口:client.TradeClose()
      • 统一收单交易退款接口:client.TradeRefund()
      • 统一收单退款页面接口:client.TradePageRefund()
      • 统一收单交易退款查询:client.TradeFastPayRefundQuery()
      • 统一收单交易结算接口:client.TradeOrderSettle()
    • 网页&移动应用 - 资金API
      • 单笔转账接口:client.FundTransUniTransfer()
      • 查询转账订单接口: client.FundTransOrderQuery()
      • 支付宝资金账户资产查询接口:client.FundAccountQuery()
      • 转账业务单据查询接口:client.FundTransCommonQuery()
      • 资金退回接口: client.FundTransRefund()
      • 资金授权冻结接口: client.FundAuthOrderFreeze()
      • 资金授权发码接口: client.FundAuthOrderVoucherCreate()
      • 线上资金授权冻结接口: client:FundAuthOrderAppFreeze()
      • 资金授权解冻接口: client.FundAuthOrderUnfreeze()
      • 资金授权操作查询接口: client.FundAuthOperationDetailQuery()
      • 资金授权撤销接口: client.FundAuthOperationCancel()
      • 批次下单接口: client.FundBatchCreate()
      • 批量转账关单接口: client.FundBatchClose()
      • 批量转账明细查询接口: client.FundBatchDetailQuery()
      • 现金红包无线支付接口: client.FundTransAppPay()
    • 网页&移动应用 - 会员API
      • 支付宝会员授权信息查询接口(App支付宝登录):client.UserInfoShare()
      • 身份认证初始化服务:client.UserCertifyOpenInit()
      • 身份认证开始认证(获取认证链接):client.UserCertifyOpenCertify()
      • 身份认证记录查询:client.UserCertifyOpenQuery()
    • 网页&移动应用 - 工具类API
      • 用户登陆授权:client.UserInfoAuth()
      • 换取授权访问令牌(获取access_token,user_id等信息):client.SystemOauthToken()
      • 换取应用授权令牌(获取app_auth_token,auth_app_id,user_id等信息):client.OpenAuthTokenApp()
    • 网页&移动应用 - 芝麻信用API
      • 获取芝麻信用分:client.ZhimaCreditScoreGet()(失效)
    • 网页&移动应用 - 财务API
      • 支付宝商家账户当前余额查询:client.DataBillBalanceQuery()(失效)
      • 查询对账单下载地址:client.DataBillDownloadUrlQuery()

    支付宝公共API

    • alipay.GetCertSN() => 获取证书SN号(app_cert_sn、alipay_cert_sn)
    • alipay.GetRootCertSN() => 获取证书SN号(alipay_root_cert_sn)
    • alipay.GetRsaSign() => 获取支付宝参数签名(参数sign值)
    • alipay.SystemOauthToken() => 换取授权访问令牌(得到access_token,user_id等信息)
    • alipay.FormatPrivateKey() => 格式化应用私钥
    • alipay.FormatPublicKey() => 格式化支付宝公钥
    • alipay.FormatURLParam() => 格式化支付宝请求URL参数
    • alipay.ParseNotifyToBodyMap() => 解析支付宝支付异步通知的参数到BodyMap
    • alipay.ParseNotifyByURLValues() => 通过 url.Values 解析支付宝支付异步通知的参数到BodyMap
    • alipay.VerifySign() => 支付宝异步通知参数验签
    • alipay.VerifySignWithCert() => 支付宝异步通知参数验签(证书方式)
    • alipay.VerifySyncSign() => 支付宝同步返回参数验签
    • alipay.DecryptOpenDataToStruct() => 解密支付宝开放数据到 结构体
    • alipay.DecryptOpenDataToBodyMap() => 解密支付宝开放数据到 BodyMap
    • alipay.MonitorHeartbeatSyn() => 验签接口

    二、文档说明

    • GoPay 文档地址
    • QQ支付 使用方法请参考微信的
    • 所有方法,如有问题,请仔细查看 wechat/client_test.go、alipay/client_test.go 或 examples
    • 有问题请加QQ群(加群验证答案:gopay),微信加好友拉群(微信群比较活跃)。在此,非常感谢那些加群后,提出意见和反馈问题的同志们!

    QQ群:

    加微信邀请加入微信群:


    1、初始化GoPay客户端并做配置(HTTP请求均默认设置tls.Config{InsecureSkipVerify: true})

    • 微信V3(推荐)

    注意:V3 版本接口持续增加中,并未做沙箱支付,测试请用1分钱测试法

    具体使用介绍,请参考 gopay/wechat/v3/client_test.go

    import (
    	"github.com/go-pay/gopay/wechat/v3"
    )
    
    // NewClientV3 初始化微信客户端 V3
    //	appid:appid 或者服务商模式的 sp_appid
    //	mchid:商户ID 或者服务商模式的 sp_mchid
    // 	serialNo:商户证书的证书序列号
    //	apiV3Key:apiV3Key,商户平台获取
    //	pkContent:私钥 apiclient_key.pem 读取后的内容
    client, err = NewClientV3(Appid, MchId, SerialNo, ApiV3Key, PKContent)
    if err != nil {
        xlog.Error(err)
        return
    }
    
    // 自动验签
    // 注意:未获取到微信平台公钥时,不要开启,请调用 client.GetPlatformCerts() 获取微信平台证书公钥
    //client.AutoVerifySign("微信平台公钥")
    
    // 打开Debug开关,输出日志
    client.DebugSwitch = gopay.DebugOff
    
    • 微信V2

    微信官方文档:官方文档

    注意:微信支付下单等操作可用沙箱环境测试是否成功,但真正支付时,请使用正式环境 isProd = true,不然会报错。

    微信证书二选一:只传 apiclient_cert.pem 和 apiclient_key.pem 或者只传 apiclient_cert.p12

    import (
    	"github.com/go-pay/gopay/wechat"
    )
    
    // 初始化微信客户端
    //    appId:应用ID
    //    mchId:商户ID
    //    apiKey:API秘钥值
    //    isProd:是否是正式环境
    client := wechat.NewClient("wxdaa2ab9ef87b5497", mchId, apiKey, false)
    
    // 打开Debug开关,输出请求日志,默认关闭
    client.DebugSwitch = gopay.DebugOn
    
    // 设置国家:不设置默认 中国国内
    //    wechat.China:中国国内
    //    wechat.China2:中国国内备用
    //    wechat.SoutheastAsia:东南亚
    //    wechat.Other:其他国家
    client.SetCountry(wechat.China)
    
    // 添加微信pem证书
    client.AddCertPemFilePath()
    client.AddCertPemFileContent()
    
    // 添加微信pkcs12证书
    client.AddCertPkcs12FilePath()
    client.AddCertPkcs12FileContent()
    
    • 支付宝

    支付宝官方文档:官方文档

    支付宝RSA秘钥生成文档:生成RSA密钥 (推荐使用 RSA2)

    沙箱环境使用说明:文档地址

    import (
        "github.com/go-pay/gopay/alipay"
    )
    
    // 初始化支付宝客户端
    //    appId:应用ID
    //    privateKey:应用私钥,支持PKCS1和PKCS8
    //    isProd:是否是正式环境
    client := alipay.NewClient("2016091200494382", privateKey, false)
    
    // 打开Debug开关,输出日志,默认关闭
    client.DebugSwitch = gopay.DebugOn
    
    // 设置支付宝请求 公共参数
    //    注意:具体设置哪些参数,根据不同的方法而不同,此处列举出所有设置参数
    client.SetLocation().                       // 设置时区,不设置或出错均为默认服务器时间
        SetPrivateKeyType().                    // 设置 支付宝 私钥类型,alipay.PKCS1 或 alipay.PKCS8,默认 PKCS1
        SetAliPayRootCertSN().                  // 设置支付宝根证书SN,通过 alipay.GetRootCertSN() 获取
        SetAppCertSN().                         // 设置应用公钥证书SN,通过 alipay.GetCertSN() 获取
        SetAliPayPublicCertSN().                // 设置支付宝公钥证书SN,通过 alipay.GetCertSN() 获取
        SetCharset("utf-8").                    // 设置字符编码,不设置默认 utf-8
        SetSignType(alipay.RSA2).               // 设置签名类型,不设置默认 RSA2
        SetReturnUrl("https://www.fumm.cc").  // 设置返回URL
        SetNotifyUrl("https://www.fumm.cc").  // 设置异步通知URL
        SetAppAuthToken().                      // 设置第三方应用授权
        SetAuthToken()                          // 设置个人信息授权
    
    // 证书路径
    err := client.SetCertSnByPath("appCertPublicKey.crt", "alipayRootCert.crt", "alipayCertPublicKey_RSA2.crt")
    // 证书内容
    err := client.SetCertSnByContent("appCertPublicKey bytes", "alipayRootCert bytes", "alipayCertPublicKey_RSA2 bytes")
    

    2、初始化并赋值BodyMap(client的方法所需的入参)

    • 微信请求参数

      • 微信V2接口通用参数(mch_id、appid、sign)无需传入,client 请求时会默认处理

    具体参数请根据不同接口查看:微信支付接口文档

    import (
        "github.com/go-pay/gopay/pkg/util"
    	"github.com/go-pay/gopay/wechat"
    )
    
    // 初始化 BodyMap
    bm := make(gopay.BodyMap)
    bm.Set("nonce_str", util.GetRandomString(32)).
        Set("body", "H5支付").
        Set("out_trade_no", number).
        Set("total_fee", 1).
        Set("spbill_create_ip", "127.0.0.1").
        Set("notify_url", "https://www.fumm.cc").
        Set("trade_type", TradeType_H5).
        Set("device_info", "WEB").
        Set("sign_type", SignType_MD5).
        SetBodyMap("scene_info", func(bm gopay.BodyMap) {
            bm.SetBodyMap("h5_info", func(bm gopay.BodyMap) {
                bm.Set("type", "Wap")
                bm.Set("wap_url", "https://www.fumm.cc")
                bm.Set("wap_name", "H5测试支付")
            })
        }) /*.Set("openid", "o0Df70H2Q0fY8JXh1aFPIRyOBgu8")*/
    
    // 参数 sign ,可单独生成赋值到BodyMap中;也可不传sign参数,client内部会自动获取
    // 如需单独赋值 sign 参数,需通过下面方法,最后获取sign值并在最后赋值此参数
    sign := wechat.GetParamSign("wxdaa2ab9ef87b5497", mchId, apiKey, body)
    // sign, _ := wechat.GetSanBoxParamSign("wxdaa2ab9ef87b5497", mchId, apiKey, body)
    bm.Set("sign", sign)
    
    • 支付宝请求参数

    具体参数请根据不同接口查看:支付宝支付API接口文档

    // 初始化 BodyMap
    bm := make(gopay.BodyMap)
    bm.Set("subject", "手机网站测试支付").
        Set("out_trade_no", "GZ201909081743431443").
        Set("quit_url", "https://www.fumm.cc").
        Set("total_amount", "100.00").
        Set("product_code", "QUICK_WAP_WAY")
    

    3、client 方法调用

    • 微信V3 client(推荐)

    // 直连商户
    wxRsp, err := client.V3TransactionApp(bm)
    wxRsp, err := client.V3TransactionJsapi(bm)
    wxRsp, err := client.V3TransactionNative(bm)
    wxRsp, err := client.V3TransactionH5(bm)
    wxRsp, err := client.V3TransactionQueryOrder(bm)
    wxRsp, err := client.V3TransactionCloseOrder(bm)
    
    // 服务商
    wxRsp, err := client.V3PartnerTransactionApp(bm)
    wxRsp, err := client.V3PartnerTransactionJsapi(bm)
    wxRsp, err := client.V3PartnerTransactionNative(bm)
    wxRsp, err := client.V3PartnerTransactionH5(bm)
    wxRsp, err := client.V3PartnerQueryOrder(bm)
    wxRsp, err := client.V3PartnerCloseOrder(bm)
    
    // 合单
    wxRsp, err := client.V3CombineTransactionApp(bm)
    wxRsp, err := client.V3CombineTransactionJsapi(bm)
    wxRsp, err := client.V3CombineTransactionNative(bm)
    wxRsp, err := client.V3CombineTransactionH5(bm)
    wxRsp, err := client.V3CombineQueryOrder(bm)
    wxRsp, err := client.V3CombineCloseOrder(bm)
    
    • 微信V2 client

    wxRsp, err := client.UnifiedOrder(bm)
    wxRsp, err := client.Micropay(bm)
    wxRsp, err := client.QueryOrder(bm)
    wxRsp, err := client.CloseOrder(bm)
    wxRsp, err := client.Reverse(bm)
    wxRsp, err := client.Refund(bm)
    wxRsp, err := client.QueryRefund(bm)
    wxRsp, err := client.DownloadBill(bm)
    wxRsp, err := client.DownloadFundFlow(bm)
    wxRsp, err := client.BatchQueryComment(bm)
    wxRsp, err := client.Transfer(bm)
    
    • 支付宝 client

    // 手机网站支付是通过服务端获取支付URL后,然后返回给客户端,请求URL地址即可打开支付页面
    payUrl, err := client.TradeWapPay(bm)
    
    // 电脑网站支付是通过服务端获取支付URL后,然后返回给客户端,请求URL地址即可打开支付页面
    payUrl, err := client.TradePagePay(bm)
    
    // APP支付是通过服务端获取支付参数后,然后通过Android/iOS客户端的SDK调用支付功能
    payParam, err := client.TradeAppPay(bm)
    
    // 商家使用扫码枪等条码识别设备扫描用户支付宝钱包上的条码/二维码,完成收款
    aliRsp, err := client.TradePay(bm)
    
    // 支付宝小程序支付时 buyer_id 为必传参数,需要提前获取,获取方法如下两种
    //    1、alipay.SystemOauthToken()     返回取值:rsp.SystemOauthTokenResponse.UserId
    //    2、client.SystemOauthToken()    返回取值:aliRsp.SystemOauthTokenResponse.UserId
    aliRsp, err := client.TradeCreate(bm)
    aliRsp, err := client.TradeQuery(bm)
    aliRsp, err := client.TradeClose(bm)
    aliRsp, err := client.TradeCancel(bm)
    aliRsp, err := client.TradeRefund(bm)
    aliRsp, err := client.TradePageRefund(bm)
    aliRsp, err := client.TradeFastPayRefundQuery(bm)
    aliRsp, err := client.TradeOrderSettle(bm)
    aliRsp, err := client.TradePrecreate(bm)
    aliRsp, err := client.FundTransUniTransfer(bm)
    aliRsp, err := client.FundTransCommonQuery(bm)
    aliRsp, err := client.FundAccountQuery(bm)
    aliRsp, err := client.SystemOauthToken(bm)
    aliRsp, err := client.OpenAuthTokenApp(bm)
    aliRsp, err := client.ZhimaCreditScoreGet(bm)
    aliRsp, err := client.UserCertifyOpenInit(bm)
    aliRsp, err := client.UserCertifyOpenCertify(bm)
    aliRsp, err := client.UserCertifyOpenQuery(bm)
    

    4、微信统一下单后,获取微信小程序支付、APP支付、微信内H5支付所需要的 paySign

    • 微信V3(推荐)

    小程序调起支付API:小程序调起支付API

    APP调起支付API:APP调起支付API

    JSAPI调起支付API:JSAPI调起支付API

    H5调起支付API:H5调起支付API

    // jsapi
    jsapi, err := client.PaySignOfJSAPI("prepayid")
    // app
    app, err := client.PaySignOfApp("prepayid")
    // 小程序
    applet, err := client.PaySignOfApplet("prepayid")
    
    • 微信V2

    微信小程序支付官方文档:微信小程序支付API

    APP支付官方文档:APP端调起支付的参数列表文档

    微信内H5支付官方文档:微信内H5支付文档

    import (
    	"github.com/go-pay/gopay/wechat"
    )
    
    // ====微信小程序 paySign====
    timeStamp := strconv.FormatInt(time.Now().Unix(), 10)
    packages := "prepay_id=" + wxRsp.PrepayId   // 此处的 wxRsp.PrepayId ,统一下单成功后得到
    // 获取微信小程序支付的 paySign
    //    appId:AppID
    //    nonceStr:随机字符串
    //    packages:统一下单成功后拼接得到的值
    //    signType:签名方式,务必与统一下单时用的签名方式一致
    //    timeStamp:时间
    //    apiKey:API秘钥值
    paySign := wechat.GetMiniPaySign(AppID, wxRsp.NonceStr, packages, wechat.SignType_MD5, timeStamp, apiKey)
    
    // ====APP支付 paySign====
    timeStamp := strconv.FormatInt(time.Now().Unix(), 10)
    // 获取APP支付的 paySign
    // 注意:package 参数因为是固定值,无需开发者再传入
    //    appId:AppID
    //    partnerid:partnerid
    //    nonceStr:随机字符串
    //    prepayId:统一下单成功后得到的值
    //    signType:签名方式,务必与统一下单时用的签名方式一致
    //    timeStamp:时间
    //    apiKey:API秘钥值
    paySign := wechat.GetAppPaySign(appid, partnerid, wxRsp.NonceStr, wxRsp.PrepayId, wechat.SignType_MD5, timeStamp, apiKey)
    
    // ====微信内H5支付 paySign====
    timeStamp := strconv.FormatInt(time.Now().Unix(), 10)
    packages := "prepay_id=" + wxRsp.PrepayId   // 此处的 wxRsp.PrepayId ,统一下单成功后得到
    // 获取微信内H5支付 paySign
    //    appId:AppID
    //    nonceStr:随机字符串
    //    packages:统一下单成功后拼接得到的值
    //    signType:签名方式,务必与统一下单时用的签名方式一致
    //    timeStamp:时间
    //    apiKey:API秘钥值
    paySign := wechat.GetH5PaySign(AppID, wxRsp.NonceStr, packages, wechat.SignType_MD5, timeStamp, apiKey)
    

    5、同步返回参数验签Sign、异步通知参数解析和验签Sign、异步通知返回

    异步参数需要先解析,解析出来的结构体或BodyMap再验签

    Gin Web框架

    Echo Web框架

    异步通知处理完后,需回复平台固定数据

    • 微信V3(推荐)

    import (
    	"github.com/go-pay/gopay/wechat"
        "github.com/go-pay/gopay/pkg/xlog"
    )
    
    // ========同步微信V3支付验签========
    wxRsp, err := client.V3TransactionJsapi(bm)
    if err != nil {
        xlog.Error(err)
        return
    }
    err = wechat.V3VerifySign(wxRsp.SignInfo.HeaderTimestamp, wxRsp.SignInfo.HeaderNonce, wxRsp.SignInfo.SignBody, wxRsp.SignInfo.HeaderSignature, WxPkContent)
    if err != nil {
        xlog.Error(err)
        return
    }
    
    // ========异步通知验签========
    notifyReq, err := wechat.V3ParseNotify()
    if err != nil {
        xlog.Error(err)
        return
    }
    err = notifyReq.VerifySign(WxPkContent)
    if err != nil {
        xlog.Error(err)
        return
    }
    // ========异步通知解密========
    // 普通支付通知解密
    result, err := notifyReq.DecryptCipherText(apiV3Key)
    // 合单支付通知解密
    result, err := notifyReq.DecryptCombineCipherText(apiV3Key)
    // 退款通知解密
    result, err := notifyReq.DecryptRefundCipherText(apiV3Key)
    
    // ========异步通知应答========
    // 退款通知http应答码为200且返回状态码为SUCCESS才会当做商户接收成功,否则会重试。
    // 注意:重试过多会导致微信支付端积压过多通知而堵塞,影响其他正常通知。
    
    // 此写法是 gin 框架返回微信的写法
    c.JSON(http.StatusOK, &wechat.V3NotifyRsp{Code: gopay.SUCCESS, Message: "成功"})
    // 此写法是 echo 框架返回微信的写法
    return c.JSON(http.StatusOK, &wechat.V3NotifyRsp{Code: gopay.SUCCESS, Message: "成功"})
    
    • 微信V2

    import (
    	"github.com/go-pay/gopay"
    	"github.com/go-pay/gopay/wechat"
    )
    
    // ====同步返回参数验签Sign====
    wxRsp, err := client.UnifiedOrder(bm)
    // 微信同步返回参数验签或异步通知参数验签
    //    apiKey:API秘钥值
    //    signType:签名类型(调用API方法时填写的类型)
    //    bean:微信同步返回的结构体 wxRsp 或 异步通知解析的结构体 notifyReq
    //    返回参数 ok:是否验签通过
    //    返回参数 err:错误信息
    ok, err := wechat.VerifySign(apiKey, wechat.SignType_MD5, wxRsp)
    
    // ====支付异步通知参数解析和验签Sign====
    // 解析支付异步通知的参数
    //    req:*http.Request
    //    ctx.Request   是 gin 框架的获取 *http.Request
    //    ctx.Request() 是 echo 框架的获取 *http.Request
    //    返回参数 notifyReq:通知的参数
    //    返回参数 err:错误信息
    notifyReq, err := wechat.ParseNotifyToBodyMap(ctx.Request)
    
    // 验签操作
    ok, err := wechat.VerifySign(apiKey, wechat.SignType_MD5, notifyReq)
    
    // ====退款异步通知参数解析,退款通知无sign,不用验签====
    // 
    // 解析退款异步通知的参数,解析出来的 req_info 是加密数据,需解密
    //    req:*http.Request
    //    ctx.Request   是 gin 框架的获取 *http.Request
    //    ctx.Request() 是 echo 框架的获取 *http.Request
    //    返回参数 notifyReq:通知的参数
    //    返回参数 err:错误信息
    notifyReq, err := wechat.ParseNotifyToBodyMap(c.Request)
     或
    notifyReq, err := wechat.ParseRefundNotify(c.Request)
    
    // ==解密退款异步通知的加密参数 req_info ==
    refundNotify, err := wechat.DecryptRefundNotifyReqInfo(notifyReq.ReqInfo, apiKey)
    
    // ==异步通知,返回给微信平台的信息==
    rsp := new(wechat.NotifyResponse) // 回复微信的数据
    rsp.ReturnCode = gopay.SUCCESS
    rsp.ReturnMsg = gopay.OK
    
    // 此写法是 gin 框架返回微信的写法
    c.String(http.StatusOK, "%s", rsp.ToXmlString())
    // 此写法是 echo 框架返回微信的写法
    return c.String(http.StatusOK, rsp.ToXmlString())
    
    • 支付宝

    注意:APP支付、手机网站支付、电脑网站支付 暂不支持同步返回验签

    支付宝支付后的同步/异步通知验签文档:支付结果通知

    import (
    	"github.com/go-pay/gopay/alipay"
    )
    
    // ====同步返回参数验签Sign====
    aliRsp, err := client.TradePay(bm)
    // 支付宝同步返回验签
    //    注意:APP支付,手机网站支付,电脑网站支付 暂不支持同步返回验签
    //    aliPayPublicKey:支付宝平台获取的支付宝公钥
    //    signData:待验签参数,aliRsp.SignData
    //    sign:待验签sign,aliRsp.Sign
    //    返回参数ok:是否验签通过
    //    返回参数err:错误信息
    ok, err := alipay.VerifySyncSign(aliPayPublicKey, aliRsp.SignData, aliRsp.Sign)
    //    aliPayPublicKeyCert:支付宝公钥证书存放路径 alipayCertPublicKey_RSA2.crt 或文件内容[]byte
    ok, err := alipay.VerifySyncSignWithCert(aliPayPublicKeyCert, aliRsp.SignData, aliRsp.Sign)
    
    // ====异步通知参数解析和验签Sign====
    // 解析异步通知的参数
    //    req:*http.Request
    //    返回参数 notifyReq:通知的参数
    //    返回参数 err:错误信息
    notifyReq, err = alipay.ParseNotifyToBodyMap(c.Request())     // c.Request()是 echo 框架的获取
     或
    notifyReq, err = alipay.ParseNotifyByURLValues()
    
    // 验签操作
    ok, err = alipay.VerifySign(aliPayPublicKey, notifyReq)
    // 证书验签操作
    ok, err = alipay.VerifySignWithCert("alipayCertPublicKey_RSA2.crt", notifyReq)
    
    // ==异步通知,返回支付宝平台的信息==
    //    文档:https://opendocs.alipay.com/open/203/105286
    //    程序执行完后必须打印输出“success”(不包含引号)。如果商户反馈给支付宝的字符不是success这7个字符,支付宝服务器会不断重发通知,直到超过24小时22分钟。一般情况下,25小时以内完成8次通知(通知的间隔频率一般是:4m,10m,10m,1h,2h,6h,15h)
    
    // 此写法是 gin 框架返回支付宝的写法
    c.String(http.StatusOK, "%s", "success")
    // 此写法是 echo 框架返回支付宝的写法
    return c.String(http.StatusOK, "success")
    

    6、微信、支付宝 公共API(仅部分说明)

    • 微信V2 公共API

    官方文档:code2Session

    button按钮获取手机号码:button组件文档

    微信解密算法文档:解密算法文档

    import (
    	"github.com/go-pay/gopay/wechat"
    )
    
    // 获取微信小程序用户的OpenId、SessionKey、UnionId
    //    appId:微信小程序的APPID
    //    appSecret:微信小程序的AppSecret
    //    wxCode:小程序调用wx.login 获取的code
    sessionRsp, err := wechat.Code2Session(appId, appSecret, wxCode)
    
    // ====解密微信加密数据到指定结构体====
    
    //小程序获取手机号
    data := "Kf3TdPbzEmhWMuPKtlKxIWDkijhn402w1bxoHL4kLdcKr6jT1jNcIhvDJfjXmJcgDWLjmBiIGJ5acUuSvxLws3WgAkERmtTuiCG10CKLsJiR+AXVk7B2TUQzsq88YVilDz/YAN3647REE7glGmeBPfvUmdbfDzhL9BzvEiuRhABuCYyTMz4iaM8hFjbLB1caaeoOlykYAFMWC5pZi9P8uw=="
    iv := "Cds8j3VYoGvnTp1BrjXdJg=="
    session := "lyY4HPQbaOYzZdG+JcYK9w=="
    phone := new(wechat.UserPhone)
    // 解密开放数据
    //    encryptedData:包括敏感数据在内的完整用户信息的加密数据,小程序获取到
    //    iv:加密算法的初始向量,小程序获取到
    //    sessionKey:会话密钥,通过 wechat.Code2Session() 方法获取到
    //    beanPtr:需要解析到的结构体指针,操作完后,声明的结构体会被赋值
    err := wechat.DecryptOpenDataToStruct(data, iv, session, phone)
    xlog.Debug(*phone)
    // 获取微信小程序用户信息
    sessionKey := "tiihtNczf5v6AKRyjwEUhQ=="
    encryptedData := "CiyLU1Aw2KjvrjMdj8YKliAjtP4gsMZMQmRzooG2xrDcvSnxIMXFufNstNGTyaGS9uT5geRa0W4oTOb1WT7fJlAC+oNPdbB+3hVbJSRgv+4lGOETKUQz6OYStslQ142dNCuabNPGBzlooOmB231qMM85d2/fV6ChevvXvQP8Hkue1poOFtnEtpyxVLW1zAo6/1Xx1COxFvrc2d7UL/lmHInNlxuacJXwu0fjpXfz/YqYzBIBzD6WUfTIF9GRHpOn/Hz7saL8xz+W//FRAUid1OksQaQx4CMs8LOddcQhULW4ucetDf96JcR3g0gfRK4PC7E/r7Z6xNrXd2UIeorGj5Ef7b1pJAYB6Y5anaHqZ9J6nKEBvB4DnNLIVWSgARns/8wR2SiRS7MNACwTyrGvt9ts8p12PKFdlqYTopNHR1Vf7XjfhQlVsAJdNiKdYmYVoKlaRv85IfVunYzO0IKXsyl7JCUjCpoG20f0a04COwfneQAGGwd5oa+T8yO5hzuyDb/XcxxmK01EpqOyuxINew=="
    iv2 := "r7BXXKkLb8qrSNn05n0qiA=="
    
    // 微信小程序 用户信息
    userInfo := new(wechat.AppletUserInfo)
    err = wechat.DecryptOpenDataToStruct(encryptedData, iv2, sessionKey, userInfo)
    xlog.Debug(*userInfo)
    
    data := "Kf3TdPbzEmhWMuPKtlKxIWDkijhn402w1bxoHL4kLdcKr6jT1jNcIhvDJfjXmJcgDWLjmBiIGJ5acUuSvxLws3WgAkERmtTuiCG10CKLsJiR+AXVk7B2TUQzsq88YVilDz/YAN3647REE7glGmeBPfvUmdbfDzhL9BzvEiuRhABuCYyTMz4iaM8hFjbLB1caaeoOlykYAFMWC5pZi9P8uw=="
    iv := "Cds8j3VYoGvnTp1BrjXdJg=="
    session := "lyY4HPQbaOYzZdG+JcYK9w=="
        
    // 解密开放数据到 BodyMap
    //    encryptedData:包括敏感数据在内的完整用户信息的加密数据
    //    iv:加密算法的初始向量
    //    sessionKey:会话密钥
    bm, err := wechat.DecryptOpenDataToBodyMap(data, iv, session)
    if err != nil {
         xlog.Debug("err:", err)
         return
    }
    xlog.Debug("WeChatUserPhone:", bm)
    
    • 支付宝 公共API

    支付宝换取授权访问令牌文档:换取授权访问令牌

    获取用户手机号文档:获取用户手机号

    支付宝加解密文档:AES配置文档AES加解密文档

    import (
    	"github.com/go-pay/gopay/alipay"
    )
    
    // 换取授权访问令牌(默认使用utf-8,RSA2)
    //    appId:应用ID
    //    privateKey:应用私钥,支持PKCS1和PKCS8
    //    grantType:值为 authorization_code 时,代表用code换取;值为 refresh_token 时,代表用refresh_token换取,传空默认code换取
    //    codeOrToken:支付宝授权码或refresh_token
    rsp, err := alipay.SystemOauthToken(appId, privateKey, grantType, codeOrToken)
    
    // 解密支付宝开放数据带到指定结构体
    //    以小程序获取手机号为例
    phone := new(alipay.UserPhone)
    // 解密支付宝开放数据
    //    encryptedData:包括敏感数据在内的完整用户信息的加密数据
    //    secretKey:AES密钥,支付宝管理平台配置
    //    beanPtr:需要解析到的结构体指针
    err := alipay.DecryptOpenDataToStruct(encryptedData, secretKey, phone)
    xlog.Debug(*phone)
    

    至此:

    如果您觉得本文对您有所帮助,请移步 Github 给作者一颗小星星吧

    赞赏多少是您的心意,感谢!

    微信: 支付宝:

    展开全文
  • 微信支付

    2018-08-14 23:02:37
    微信支付平台 https://pay.weixin.qq.com/index.php/core/home/login?return_url=%2F 微信支付准备资料 扫码支付可分为两种模式,商户根据支付场景选择相应模式。 模式一 商户后台系统根据微信支付规则链接...

    微信支付平台

    https://pay.weixin.qq.com/index.php/core/home/login?return_url=%2F

    微信支付准备资料

    扫码支付可分为两种模式,商户根据支付场景选择相应模式。

    模式一

    商户后台系统根据微信支付规则链接生成二维码,链接中带固定参数productid(可定义为产品标识或订单号)。用户扫码后,微信支付系统将productid和用户唯一标识(openid)回调商户后台系统(需要设置支付回调URL),商户后台系统根据productid生成支付交易,最后微信支付系统发起用户支付流程。

    商户支付回调URL设置指引:进入商户平台-->产品中心-->开发配置,进行配置和修改,如图6.6所示。

    扫码支付参数设置栏目入口

    图6.6 扫码支付回调URL设置

    设置完成后,详细接入步骤:模式一

    【模式二】:商户后台系统调用微信支付【统一下单API】生成预付交易,将接口返回的链接生成二维码,用户扫码后输入密码完成支付交易。注意:该模式的预付单有效期为2小时,过期后无法支付。

     

    模式二

    模式二与模式一相比,流程更为简单,不依赖设置的回调支付URL。商户后台系统先调用微信支付的统一下单接口,微信后台系统返回链接参数code_url,商户后台系统将code_url值生成二维码图片,用户使用微信客户端扫码后发起支付。注意:code_url有效期为2小时,过期后扫码不能再发起支付。

    业务流程时序图

    原生支付模式二时序图

    原生支付模式二时序图

    业务流程说明:

    (1)商户后台系统根据用户选购的商品生成订单。

    (2)用户确认支付后调用微信支付【统一下单API】生成预支付交易;

    (3)微信支付系统收到请求后生成预支付交易单,并返回交易会话的二维码链接code_url。

    (4)商户后台系统根据返回的code_url生成二维码。

    (5)用户打开微信“扫一扫”扫描二维码,微信客户端将扫码内容发送到微信支付系统。

    (6)微信支付系统收到客户端请求,验证链接有效性后发起用户支付,要求用户授权。

    (7)用户在微信客户端输入密码,确认支付后,微信客户端提交授权。

    (8)微信支付系统根据用户授权完成支付交易。

    (9)微信支付系统完成支付交易后给微信客户端返回交易结果,并将交易结果通过短信、微信消息提示用户。微信客户端展示支付交易结果页面。

    (10)微信支付系统通过发送异步消息通知商户后台系统支付结果。商户后台系统需回复接收情况,通知微信后台系统不再发送该单的支付通知。

    (11)未收到支付通知的情况,商户后台系统调用【查询订单API】。

    (12)商户确认订单已支付后给用户发货。

    生成二维码规则

    对应链接格式:weixin://wxpay/bizpayurl?sr=XXXXX。请商户调用第三方库将code_url生成二维码图片。该模式链接较短,生成的二维码打印到结账小票上的识别率较高。

     

    统一下单

    应用场景

    除被扫支付场景以外,商户系统先调用该接口在微信支付服务后台生成预支付交易单,返回正确的预支付交易会话标识后再按扫码、JSAPI、APP等不同场景生成交易串调起支付。

    状态机

    支付状态转变如下:

    接口链接

    URL地址:https://api.mch.weixin.qq.com/pay/unifiedorder

    是否需要证书

    请求参数

    字段名变量名必填类型示例值描述
    公众账号IDappidString(32)wxd678efh567hg6787微信支付分配的公众账号ID(企业号corpid即为此appId)
    商户号mch_idString(32)1230000109微信支付分配的商户号
    设备号device_infoString(32)013467007045764自定义参数,可以为终端设备号(门店号或收银设备ID),PC网页或公众号内支付可以传"WEB"
    随机字符串nonce_strString(32)5K8264ILTKCH16CQ2502SI8ZNMTM67VS随机字符串,长度要求在32位以内。推荐随机数生成算法
    签名signString(32)C380BEC2BFD727A4B6845133519F3AD6通过签名算法计算得出的签名值,详见签名生成算法
    签名类型sign_typeString(32)MD5签名类型,默认为MD5,支持HMAC-SHA256和MD5。
    商品描述bodyString(128)腾讯充值中心-QQ会员充值

    商品简单描述,该字段请按照规范传递,具体请见参数规定

    商品详情detailString(6000) 商品详细描述,对于使用单品优惠的商户,改字段必须按照规范上传,详见“单品优惠参数说明”
    附加数据attachString(127)深圳分店附加数据,在查询API和支付通知中原样返回,可作为自定义参数使用。
    商户订单号out_trade_noString(32)20150806125346商户系统内部订单号,要求32个字符内,只能是数字、大小写字母_-|* 且在同一个商户号下唯一。详见商户订单号
    标价币种fee_typeString(16)CNY符合ISO 4217标准的三位字母代码,默认人民币:CNY,详细列表请参见货币类型
    标价金额total_feeInt88订单总金额,单位为分,详见支付金额
    终端IPspbill_create_ipString(16)123.12.12.123APP和网页支付提交用户端ip,Native支付填调用微信支付API的机器IP。
    交易起始时间time_startString(14)20091225091010订单生成时间,格式为yyyyMMddHHmmss,如2009年12月25日9点10分10秒表示为20091225091010。其他详见时间规则
    交易结束时间time_expireString(14)20091227091010

    订单失效时间,格式为yyyyMMddHHmmss,如2009年12月27日9点10分10秒表示为20091227091010。订单失效时间是针对订单号而言的,由于在请求支付的时候有一个必传参数prepay_id只有两小时的有效期,所以在重入时间超过2小时的时候需要重新请求下单接口获取新的prepay_id。其他详见时间规则

    建议:最短失效时间间隔大于1分钟

    订单优惠标记goods_tagString(32)WXG订单优惠标记,使用代金券或立减优惠功能时需要的参数,说明详见代金券或立减优惠
    通知地址notify_urlString(256)http://www.weixin.qq.com/wxpay/pay.php异步接收微信支付结果通知的回调地址,通知url必须为外网可访问的url,不能携带参数。
    交易类型trade_typeString(16)JSAPI

    JSAPI 公众号支付

    NATIVE 扫码支付

    APP APP支付

    说明详见参数规定

    商品IDproduct_idString(32)12235413214070356458058trade_type=NATIVE时(即扫码支付),此参数必传。此参数为二维码中包含的商品ID,商户自行定义。
    指定支付方式limit_payString(32)no_credit上传此参数no_credit--可限制用户不能使用信用卡支付
    用户标识openidString(128)oUpF8uMuAJO_M2pxb1Q9zNjWeS6otrade_type=JSAPI时(即公众号支付),此参数必传,此参数为微信用户在商户对应appid下的唯一标识。openid如何获取,可参考【获取openid】。企业号请使用【企业号OAuth2.0接口】获取企业号内成员userid,再调用【企业号userid转openid接口】进行转换
    +场景信息scene_infoString(256)

    {"store_info" : {
    "id": "SZTX001",
    "name": "腾大餐厅",
    "area_code": "440305",
    "address": "科技园中一路腾讯大厦" }}

    该字段用于上报场景信息,目前支持上报实际门店信息。该字段为JSON对象数据,对象格式为{"store_info":{"id": "门店ID","name": "名称","area_code": "编码","address": "地址" }} ,字段详细说明请点击行前的+展开

    举例如下:

    <xml>
       <appid>wx2421b1c4370ec43b</appid>
       <attach>支付测试</attach>
       <body>JSAPI支付测试</body>
       <mch_id>10000100</mch_id>
       <detail><![CDATA[{ "goods_detail":[ { "goods_id":"iphone6s_16G", "wxpay_goods_id":"1001", "goods_name":"iPhone6s 16G", "quantity":1, "price":528800, "goods_category":"123456", "body":"苹果手机" }, { "goods_id":"iphone6s_32G", "wxpay_goods_id":"1002", "goods_name":"iPhone6s 32G", "quantity":1, "price":608800, "goods_category":"123789", "body":"苹果手机" } ] }]]></detail>
       <nonce_str>1add1a30ac87aa2db72f57a2375d8fec</nonce_str>
       <notify_url>http://wxpay.wxutil.com/pub_v2/pay/notify.v2.php</notify_url>
       <openid>oUpF8uMuAJO_M2pxb1Q9zNjWeS6o</openid>
       <out_trade_no>1415659990</out_trade_no>
       <spbill_create_ip>14.23.150.211</spbill_create_ip>
       <total_fee>1</total_fee>
       <trade_type>JSAPI</trade_type>
       <sign>0CB01533B8C1EF103065174F50BCA001</sign>
    </xml>

    注:参数值用XML转义即可,CDATA标签用于说明数据不被XML解析器解析。

    返回结果

    字段名变量名必填类型示例值描述
    返回状态码return_codeString(16)SUCCESS

    SUCCESS/FAIL

    此字段是通信标识,非交易标识,交易是否成功需要查看result_code来判断

    返回信息return_msgString(128)OK

    当return_code为FAIL时返回信息为错误原因 ,例如

    签名失败

    参数格式校验错误

    以下字段在return_code为SUCCESS的时候有返回

    字段名变量名必填类型示例值描述
    公众账号IDappidString(32)wx8888888888888888调用接口提交的公众账号ID
    商户号mch_idString(32)1900000109调用接口提交的商户号
    设备号device_infoString(32)013467007045764自定义参数,可以为请求支付的终端设备号等
    随机字符串nonce_strString(32)5K8264ILTKCH16CQ2502SI8ZNMTM67VS微信返回的随机字符串
    签名signString(32)C380BEC2BFD727A4B6845133519F3AD6微信返回的签名值,详见签名算法
    业务结果result_codeString(16)SUCCESSSUCCESS/FAIL
    错误代码err_codeString(32) 当result_code为FAIL时返回错误代码,详细参见下文错误列表
    错误代码描述err_code_desString(128) 当result_code为FAIL时返回错误描述,详细参见下文错误列表

    以下字段在return_code 和result_code都为SUCCESS的时候有返回

    字段名变量名必填类型示例值描述
    交易类型trade_typeString(16)JSAPI

    JSAPI 公众号支付

    NATIVE 扫码支付

    APP APP支付

    说明详见参数规定

    预支付交易会话标识prepay_idString(64)wx201410272009395522657a690389285100微信生成的预支付会话标识,用于后续接口调用中使用,该值有效期为2小时
    二维码链接code_urlString(64)URl:weixin://wxpay/s/An4baqwtrade_type为NATIVE时有返回,用于生成二维码,展示给用户进行扫码支付

    举例如下:

    <xml>
       <return_code><![CDATA[SUCCESS]]></return_code>
       <return_msg><![CDATA[OK]]></return_msg>
       <appid><![CDATA[wx2421b1c4370ec43b]]></appid>
       <mch_id><![CDATA[10000100]]></mch_id>
       <nonce_str><![CDATA[IITRi8Iabbblz1Jc]]></nonce_str>
       <openid><![CDATA[oUpF8uMuAJO_M2pxb1Q9zNjWeS6o]]></openid>
       <sign><![CDATA[7921E432F65EB8ED0CE9755F0E86D72F]]></sign>
       <result_code><![CDATA[SUCCESS]]></result_code>
       <prepay_id><![CDATA[wx201411101639507cbf6ffd8b0779950874]]></prepay_id>
       <trade_type><![CDATA[JSAPI]]></trade_type>
    </xml>

    错误码

    名称描述原因解决方案
    NOAUTH商户无此接口权限商户未开通此接口权限请商户前往申请此接口权限
    NOTENOUGH余额不足用户帐号余额不足用户帐号余额不足,请用户充值或更换支付卡后再支付
    ORDERPAID商户订单已支付商户订单已支付,无需重复操作商户订单已支付,无需更多操作
    ORDERCLOSED订单已关闭当前订单已关闭,无法支付当前订单已关闭,请重新下单
    SYSTEMERROR系统错误系统超时系统异常,请用相同参数重新调用
    APPID_NOT_EXISTAPPID不存在参数中缺少APPID请检查APPID是否正确
    MCHID_NOT_EXISTMCHID不存在参数中缺少MCHID请检查MCHID是否正确
    APPID_MCHID_NOT_MATCHappid和mch_id不匹配appid和mch_id不匹配请确认appid和mch_id是否匹配
    LACK_PARAMS缺少参数缺少必要的请求参数请检查参数是否齐全
    OUT_TRADE_NO_USED商户订单号重复同一笔交易不能多次提交请核实商户订单号是否重复提交
    SIGNERROR签名错误参数签名结果不正确请检查签名参数和方法是否都符合签名算法要求
    XML_FORMAT_ERRORXML格式错误XML格式错误请检查XML参数格式是否正确
    REQUIRE_POST_METHOD请使用post方法未使用post传递参数 请检查请求参数是否通过post方法提交
    POST_DATA_EMPTYpost数据为空post数据不能为空请检查post数据是否为空
    NOT_UTF8编码格式错误未使用指定编码格式请使用UTF-8编码格式

     

    代码如下:

    第一步引入微信sdk里面的工具类

     

    第二步配置ymi文件要与微信需求到的信息的一模一样,不然会缺失参数

    #tomcat配置
    server:
      port: 8082
    
    wechatpay:
       notifyUrl: http://域名/WeChat/pay/notify #回调地址
       appId:     #应用id
       mchId:    #商户平台账号
       mchKey:  #商户平台密钥
    

     

    第三部搭建微信的配置类,注意要与yml信息一致,不然会导致注入错误

    新建config包,新建WeChatPayConfig
    
    @Component
    @ConfigurationProperties("wechatpay")
    public class WeChatPayConfig {
        /**
         * 回调地址
         */
        private String notifyUrl;
        /**
         * 应用id
         */
        private String appId;
    
        /**
         * 商户号
         */
        private String mchId;
    
        /**
         * 商户密钥
         */
        private String mchKey;
    
    
        public String getMchKey() {
            return mchKey;
        }
    
        public void setMchKey(String mchKey) {
            this.mchKey = mchKey;
        }
    
        public String getNotifyUrl() {
            return notifyUrl;
        }
    
        public void setNotifyUrl(String notifyUrl) {
            this.notifyUrl = notifyUrl;
        }
    
        public String getAppId() {
            return appId;
        }
    
        public void setAppId(String appId) {
            this.appId = appId;
        }
    
        public String getMchId() {
            return mchId;
        }
    
        public void setMchId(String mchId) {
            this.mchId = mchId;
        }
    }
    
    

     

    第四步Controller实现:,实现微信二维码链接获取和支付结果通知

    @RestController
    @RequestMapping("/WeChat/pay")
    public class WxPayController {
    
        @Autowired
        WeChatPayConfig weChatPayConfig;
    
        /**
         * @param orderNo 订单编号 由前端传入
         * @return
         */
        @RequestMapping("/createQRCode")
        public Dto createQRcode(String orderNo) {
            //1.组装请求所需要的参数
            HashMap<String, String> paramsMap = new HashMap<>();
            paramsMap.put("body", "订单支付");
            paramsMap.put("out_trade_no", orderNo); 
            //这里是我测试的,1分钱,代替了订单的价格
            paramsMap.put("total_fee", "1");
            paramsMap.put("spbill_create_ip", "自己的ip");
            paramsMap.put("notify_url", weChatPayConfig.getNotifyUrl());
            //	JSAPI 公众号支付,这里我的选择为NATIVE 扫码支付
            paramsMap.put("trade_type", "NATIVE");
            paramsMap.put("nonce_str", WXPayUtil.generateNonceStr());
            paramsMap.put("appid", weChatPayConfig.getAppId());
            paramsMap.put("mch_id", weChatPayConfig.getMchId());
    
            //2.将参数转换成xml格式,并且签名
            Map<String, String> respMap = null;
            try {
                String xmlData = WXPayUtil.generateSignedXml(paramsMap, weChatPayConfig.getMchKey());
    
                //3.请求的url:https://api.mch.weixin.qq.com/pay/unifiedorder xml格式的请求参数
                String respXml = new WXPayRequest().requestOnce("https://api.mch.weixin.qq.com/pay/unifiedorder", xmlData);
    
                //4.获取响应的结果中的code_url:二维码的链接
                respMap = WXPayUtil.xmlToMap(respXml);
    
                //5.return_code 和result_code都为SUCCESS的时候有返回
                if (respMap.get("return_code").equals(WXPayConstants.SUCCESS)
                        && respMap.get("result_code").equals(WXPayConstants.SUCCESS)) {
                    String code_url = respMap.get("code_url");
                    return DtoUtil.returnSuccess("获取二维码链接成功", code_url);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
    
            return DtoUtil.returnFail("获取二维码链接失败",
                    respMap.get("err_code") + ":" + respMap.get("err_code_des"));
        }
    
    
        /**
         * 微信异步通知支付结果
         */
        @RequestMapping("/notify")
        public String notify(HttpServletRequest request) {
            //1.利用IO获取微信异步通知XML数据
            HashMap<String, String> returnMap = null;
            try {
                InputStreamReader reader = new InputStreamReader(request.getInputStream(), "UTF-8");
                BufferedReader bufferedReader = new BufferedReader(reader);
                StringBuilder sb = new StringBuilder();
                String line;
                while ((line = bufferedReader.readLine()) != null) {
                    sb.append(line);
                }
                reader.close();
                bufferedReader.close();
    
                //2.将xml数据封转到map中
                Map<String, String> paramsMap = WXPayUtil.xmlToMap(sb.toString());
    
                //3.验签,保证安全性
                boolean signatureValid = WXPayUtil.isSignatureValid(paramsMap, weChatPayConfig.getMchKey());
                returnMap = new HashMap<>();//定义一个返回参数的map
                if (signatureValid) {//验签成功
                    String out_trade_no = paramsMap.get("out_trade_no");
                    if (paramsMap.get("return_code").equals("SUCCESS")) {//说明支付成功
                        //进行业务逻辑:在订单未支付的状态下
                        // 修改订单状态为支付成功,修改库存等
                        returnMap.put("return_code", "SUCCESS");
                        returnMap.put("return_msg", "OK");
                    } else {
                        returnMap.put("return_code", "FAIL");
                        returnMap.put("return_msg", "支付失败");
                    }
    
                } else {
                    returnMap.put("return_code", "FAIL");
                    returnMap.put("return_msg", "签名失败");
                }
    
            } catch (Exception e) {
                returnMap.put("return_code", "FAIL");
                returnMap.put("return_msg", "系统内部错误");
                e.printStackTrace();
            }
    
            String returnData = null;
            try {
                returnData = WXPayUtil.mapToXml(returnMap);
            } catch (Exception e) {
                e.printStackTrace();
            }
            return returnData;
        }
    }
    

     

    展开全文
  • vue实例项目-微商神器(在线制作微信/支付宝假红包,假聊天,假转账,假余额,花呗等截图),代码可自由更改
  • 需求:需要用余额、支付宝、微信支付方式支付会员,余额支付显示余额其余支付不显示余额余额点支付直接成功或失败,支付宝/微信支付弹出相应的二维码。支付接口为同一个,但要处理三种情况。 用到了ajax的complete...

    需求:需要用余额、支付宝、微信支付方式支付会员,余额支付显示余额其余支付不显示余额。余额点支付直接成功或失败,支付宝/微信支付弹出相应的二维码。支付接口为同一个,但要处理三种情况。
    用到了ajax的complete,return一个对象再进行判断。
    在这里插入图片描述在这里插入图片描述

    接口:
    /shared/profile/getBalance获取余额
    /shared/profile/viporder支付
    /fund/paycallback/selecttradeno订单号

    html部分

    <!-- vip开通 -->
    <div class="recharge" data-role="vip-pay-box" style="display:none">
        <div class="recharge-money" data-typeval="30">应付金额:
        <b data-role="pay-money"><?= $oneprice?></b></div>
    	<div class="vip-payment">
    		<div class="active" data-type="30">余额支付<i class="active"></i>
    			<b class="active"></b>
    		</div>
    		<div data-type="10">支付宝支付<i></i><b></b></div>
    		<div data-type="20">微信支付<i></i><b></b></div>
    	</div>
    	<div class="vip-balancebox">余额:<span class="vip-balance"></span></div>
        <div style="color:red">提示:支付成功后,请在手机或pad退出微课宝账号,
        重新登录使用会员功能</div>
    </div>
    <!-- vip开通 -->
    
    <!--VIP 充值方法-->
    <div data-role="zfbpay-qrocde" style="display:none;height:210px">
        <div class="vip-ali"><i class="ali_qrcode"></i>
    		<p>支付宝扫一扫支付</p>
    	</div>
    </div>
    <div data-role="wxpay-qrocde" style="display:none;height:210px">
        <div class="vip-wechat"><i class="wx_qrcode"></i>
    		<p>微信扫一扫支付</p>
    	</div>
    </div>
    

    css部分

    /* 会员支付方式 */
    .vip-payment{
    	display: flex;
    	justify-content: space-around;
    	align-items: center;
    	margin-bottom: 25px;
    }
    .vip-payment div{
    	flex-direction: column;
    	width: 30%;
    	line-height: 35px;
    	text-align: center;
    	border: 1px #ccc solid;
    	border-radius: 3px;
    	cursor: pointer;
    	position: relative;
    }
    .vip-payment div.active{
    	border:1px red solid;
    }
    .vip-payment div i{
    	width: 0;
    	height: 0;
    	border-bottom: 20px solid red;
    	border-left: 22px solid transparent;
    	position: absolute;
    	right: 0;
    	bottom: 0;
    	display: none;
    }
    .vip-payment div i.active,
    .vip-payment div b.active{
    	display: block;
    }
    .vip-payment div b{
    	color: #fff;
        position: absolute;
        right: 0;
        bottom: 2px;
        font-weight: normal;
    	line-height: 10px;
    	display: none;
    }
    .vip-balancebox{
    	margin-bottom: 20px;
    	display: none;
    }
    

    js部分

    1、默认为余额支付方式
    2、点击支付获取支付方式

    1、默认为余额支付方式:获取$('.recharge-money').attr('data-typeval')的值,如果为30(余额)就显示剩余余额,反之。

    //会员选择支付方式
    var vipPaytype = $('.recharge-money').attr('data-typeval');
    if(vipPaytype == '30'){
    	$('.vip-balancebox').show();
    }else{
    	$('vip-balancebox').hide();
    }
    

    2、点击支付获取支付方式:添加样式,获取当前点击的data-type的值,判断是余额还是支付宝还是微信,并赋值给$('.recharge-money')

    $('.vip-payment div').click(function(){
    	$('.vip-payment div').removeClass("active").find("i,b").hide();
    	$(this).addClass("active").find("i,b").show();
    	var vipPaytype = $(this).attr('data-type');
    	if(vipPaytype == '30'){
    		console.log('余额');
    		$('.recharge-money').attr('data-typeval','30');
    		$('.vip-balancebox').show();
    	}else if(vipPaytype == '10'){
    		console.log('支付宝');
    		$('.recharge-money').attr('data-typeval','10');
    		$('.vip-balancebox').hide();
    	}else{
    		console.log('微信');
    		$('.recharge-money').attr('data-typeval','20');
    		$('.vip-balancebox').hide();
    	}
    });
    

    3、制作支付宝二维码弹窗
    4、制作微信二维码弹窗

    //支付宝支付二维码
    function zfbQRcode(tradeno){
    	layer.open({
    		type:1,
    		title: '支付宝扫码支付',
    		area: ['470px', 'auto'], //宽高
    		content: $('[data-role="zfbpay-qrocde"]'),
    		btn: ['支付完成'],
    		shade:0,
    		yes:function () {
    			selectoder(tradeno);
    		}
    	});
    }
    
    //微信支付二维码
    function wxQRcode(tradeno){
    	layer.open({
    		type:1,
    		title: '微信扫码支付',
    		area: ['470px', 'auto'], //宽高
    		content: $('[data-role="wxpay-qrocde"]'),
    		btn: ['支付完成'],
    		shade:0,
    		yes:function () {
                   selectoder(tradeno);
    		}
    	});
    }
    

    5、支付接口
    这里将ajax封装成一个pay() 的方法,通过传money和type的参数来处理不同的支付类型,这里用到了ajax自定义回调,因为余额和支付宝微信的回调不一样,当余额大于金额时余额直接成功,而支付宝微信会返回二维码。

    余额成功的回调
    在这里插入图片描述在这里插入图片描述
    支付宝微信回调
    在这里插入图片描述在这里插入图片描述
    在这里插入图片描述在这里插入图片描述
    在这里插入图片描述 在这里插入图片描述

    function pay(month,type){
       var index = layer.load(2);
       return $.post('/shared/profile/viporder',{'month': month,'type':type}).complete(function () {
    	   layer.close(index);
       }).fail(function () {
           errorMsg('网络异常,请稍后重试');
       });
    }
    

    6、支付成功的回调与支付失败的回调,跳转的界面不同。

    var wait=10;
    function showSuccessPage() {
       $(".vipversionsbox").hide();
       $(".vipversions-success").show();
       layer.closeAll();
       wait = 10;
       countDown();
    }
    function showFailPage() {
       $(".vipversionsbox").hide();
       $(".vipversions-fail").show();
       layer.closeAll();
       wait = 10;
       countDown();
    }
    //查询
    function selectoder(tradeno){
       $.post('/fund/paycallback/selecttradeno',{'tradeno':tradeno},function(res){
           if(res.success){
               showSuccessPage();
           }else{
               showFailPage();
           }
       });
    }
    function countDown() {
      if(wait == 0){
           window.location.reload();
           return;
       }
       $('.return10 span').html(wait+"s后回到会员服务");
       wait--;
       setTimeout(function() {
           countDown();
       },1000);
    }
    

    7、获取二维码,封装成一个方法,然后传参,给到append中
    返回 图片img地址
    该知识点参考文档:生成对象
    在这里插入图片描述

    function createQrcodeImgObj(qrcodeUrl) {
      return  $('<img/>', {src: qrcodeUrl});
    }
    
    

    8、点击开通会员的按钮弹窗,点支付的时候判断是什么支付方式 ,传入不同的支付参数。
    在这里插入图片描述
    余额:
    如果var vipPaytype = $('.recharge-money').attr('data-typeval');的vipPaytype 值为30,判断余额是否充足var balance = $('.vip-balance').text();//余额
    var paymoney = $('[data-role="pay-money"]').text();//应付金额
    如果balance<paymoney ,则提示余额不足,请充值或者选择其他支付方式。
    如果balance>paymoney ,则pay传money和type,成功showSuccessPage()。

    if(vipPaytype == '30'){
    	if(parseInt(balance) < parseInt(paymoney)){
    	layer.msg('余额不足,请充值或者选择其他支付方式');
    	return;
    }
    pay(month,'30').success(function (res) {
    	   if(res.success == true){
    	       showSuccessPage();
    	   }else{
    	       errorMsg(res.message);
    	   }
    	});
    }
    

    支付宝:
    再append的时候要将之前的图片清空,传值获取回调里的qrcodeUrl ,然后append给$('.ali_qrcode')。成功的话弹出二维码的弹窗。

    if(vipPaytype == '10'){
    	$('.ali_qrcode').empty();
    	pay(month,'10').success(function (res) {
         if(res.success == true){
            let qrcodeUrl = res.data.qrcode;
            $('.ali_qrcode').append(createQrcodeImgObj(qrcodeUrl));
            zfbQRcode(res.data.tradeno);
    		$('.vip-ali').show();
         }else{
            errorMsg(res.message);
         }
      });
    }
    

    微信:
    再append的时候要将之前的图片清空,传值获取回调里的qrcodeUrl ,然后append给$('.wx_qrcode')。成功的话弹出二维码的弹窗。

    if(vipPaytype == '20'){
    $('.wx_qrcode').empty();
      pay(month,'20').success(function (res) {
          if(res.success == true){
              let qrcodeUrl = res.data.qrcode;
              $('.wx_qrcode').append(createQrcodeImgObj(qrcodeUrl));
              wxQRcode(res.data.tradeno);
    		  $('.vip-wechat').show();
          }else{
              errorMsg(res.message);
          }
      });
    }
    

    完整代码:

    //充值VIP
     $('[data-role="vip-open"]').click(function(){
         getBalance();
         var index = layer.open({
             type:1,
             title: '开通会员',
             area: ['470px', 'auto'], //宽高
             content: $('[data-role="vip-pay-box"]'),
             btn:["支付","取消"],
             yes:function () {
        var  month = $('[data-role="pay-age"].active').attr('data-month');
    	var vipPaytype = $('.recharge-money').attr('data-typeval');
    	var balance = $('.vip-balance').text();//余额
    	var paymoney = $('[data-role="pay-money"]').text();//应付金额
    	
    	if(vipPaytype == '30'){
    		if(parseInt(balance) < parseInt(paymoney)){
    			layer.msg('余额不足,请充值或者选择其他支付方式');
    			return;
    		}
    		pay(month,'30').success(function (res) {
                 if(res.success == true){
                     showSuccessPage();
                 }else{
                     errorMsg(res.message);
                 }
             });
        }else if(vipPaytype == '10'){
    		$('.ali_qrcode').empty();
    		pay(month,'10').success(function (res) {
                if(res.success == true){
                    let qrcodeUrl = res.data.qrcode;
                    $('.ali_qrcode').append(createQrcodeImgObj(qrcodeUrl));
                    zfbQRcode(res.data.tradeno);
    				$('.vip-ali').show();
                }else{
                    errorMsg(res.message);
                }
            });
    	}else{
    		$('.wx_qrcode').empty();
            pay(month,'20').success(function (res) {
                 if(res.success == true){
                     let qrcodeUrl = res.data.qrcode;
                     $('.wx_qrcode').append(createQrcodeImgObj(qrcodeUrl));
                     wxQRcode(res.data.tradeno);
    				$('.vip-wechat').show();
                 }else{
                     errorMsg(res.message);
                 }
             });
    	}
      },
       btn2: function(){
           layer.close(index);
       }
      });
     });
    
    展开全文
  • 本文是【浅析微信支付】系列文章的第十一篇,主要讲解支付验收示例和验收指引。 浅析微信支付系列已经更新十一篇了哟~,没有看过的朋友们可以看一下。 浅析微信支付:下载对账单和资金账单 浅析微信支付:申请...

    本文是【浅析微信支付】系列文章的第十一篇,主要讲解支付验收示例和验收指引。


    浅析微信支付系列已经更新十一篇了哟~,没有看过的朋友们可以看一下。

    浅析微信支付:如何使用沙箱环境测试

    浅析微信支付:下载对账单和资金账单

    浅析微信支付:申请退款、退款回调接口、查询退款

    浅析微信支付:查询订单和关闭订单

    上一篇文章我们讲了 如何使用沙箱环境测试,文中有讲到沙箱环境不仅可以用来当开发环境使用,及时返回接口数据,还能当作微信支付的 验收示例,官方指出,为了安全考虑希望所有商户都接入验收,以下我们会结合官方文档为大家讲解如何接入及相关的验收用例。

    验收指引

    官方文档地址:

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

    本文阅读对象为:商户自有系统(包括但不限于:在线购物平台、人工收银系统、自动化智能收银系统、APP应用等)负责微信支付功能验收的测试及开发人员。

    为保证商户接入质量,提升交易安全及用户体验,微信支付的合作服务商在正式上线交易前,必须先根据本文指引完成验收。验收完成后,服务商在验收公众平台(微信号:WXPayAssist)提交验收通过申请,审核通过后,才能开通相应的支付权限(如:刷卡支付)。否则,请根据审核驳回提示,重新完成验收。

    注:仿真测试环境中的商户号(父子商户号)需使用真实商户号。

    验收流程

    图2 商户接入验收流程

    如图2,商户在收到微信支付审核通过的邮件后,即可用邮件中提供的开发者信息,启动测试验收工作。验收开始后,验收负责人可按照下表步骤操作:

    验收步骤

    以上为验收的基本步骤,首先,我们需要接入 沙箱环境,不知道的小伙伴可以查看我的上一篇文章,有详细描述,这里就不细说了。

    验收测试用例

    如果已经接入沙箱环境,我们就可以开始选择微信官方对应的验收用例进行测试了,官方提供了四种验收用例,如下:

    请根据您需要开通的功能来选择相应的验收用例进行测试:

    刷卡支付验收用例
    扫码支付验收用例
    公众号支付验收用例
    免充值券验收用例

    这里我们以 公众号支付验收用例 来做例子,下面为官方的验收流程:
    公众号支付验收用例

    流程我们已经知道了,重点来了,我们需要下载验收用例,下面是地址:

    https://pay.weixin.qq.com/wiki/doc/api/download/jsapi_yanshou.zip
    

    首先,请关注上面图片中的二维码,如果遇到问题,可以查看官方的异常解答;下载验收用例后,我们会得到 4 个用例文档,需要根据文档中的描述来进行验收,支付成功支付失败接口是必须验收的。

    如何验收?

    简单讲,验收分为以下几个步骤:

    1. 获取sandbox_signkey
    2. 修改正常接口地址为沙箱环境地址,增加 sandboxnew 路径
    3. 根据用例集标题中的金额传入参数,调用相应的接口
    4. 查看返回值与用例集中是否一致,如果一致则成功,否则失败

    需要注意的是,一定要根据用例集中的标题传入金额,比如支付成功用例集需要传入金额1.01元,那我们就必须传入这个金额,传入其他金额会导致失败。

    以下为示例代码:

    public static void main(String[] args) throws Exception {
        System.out.println("--------------->");
    
        // 沙箱环境测试
        WXPay wxPay = new WXPay(WXPayConfigImpl.getInstance(), true, true);
    
        Map<String, String> resultMap = wxPay.unifiedOrder(notify_url, openid, body, out_trade_no, 
        "1.01", spbill_create_ip, goods_tag, detail,
                timeStart, timeExpire);
    
    
        System.out.println(resultMap);
    
        /*Map<String, String> resultMap = wxPay.refund(null, "10000", "10001", "1.01", "0.01", "测试微信退款");
        System.out.println(WXPayUtil.isSignatureValid(resultMap, WXPayConstants.API_KEY));*/
    
    
        System.out.println("<---------------");
    }
    

    上面代码中是作者封装好的sdk方法,开启沙箱环境只需要实例化对象时传入参数即可:

    // 沙箱环境测试
    WXPay wxPay = new WXPay(WXPayConfigImpl.getInstance(), true, true);
    
    // 正式环境
    WXPay wxPay = new WXPay(WXPayConfigImpl.getInstance());
    

    具体源码见下面文末github地址。

    结语

    给小伙伴们分享点验收的经验,首先,一定要先看一遍官方文档,然后跟着官方文档一步步的操作,对于官方所讲的关键信息,必须仔细检查,比如上面所说的金额,还有官方标红的一些注释,本文主要目的是给大家一个分享和参考,比较方便的是作者已经封装好的sdk中有相关的 沙箱环境 切换示例,不需要大家再分析具体实现,关注如何应用即可。

    如果小伙伴有遇到解决不了的问题,可以关注作者微信公众号,加入讨论群中发出疑问,和小伙伴们一起解决哦~

    预告:下一篇文章 (余额提现)企业付款到微信用户零钱账户,敬请期待!!!

    ​如果想要提前一览源码的小伙伴,可以先看看我的 github,地址如下:

    ​https://github.com/YClimb/wxpay-sdk/blob/master/README.md ​

    关注作者微信公众号,点击下方讨论群,扫码即可加入微信支付讨论群与小伙伴一起探讨哦~

    到此本文就结束了,关注公众号查看更多推送!!!


    关注我的公众号


    展开全文
  • Spring Boot入门教程(四十一):微信支付集成-扫码支付

    万次阅读 热门讨论 2018-06-18 14:21:44
    使用微信支付需要先开通服务号,然后还要开通微信支付,最后还要配置一些开发参数,过程比较多。 申请服务号(企业) 开通微信支付 开发配置 具体准备工作请参考Spring Boot入门教程(三十九):微信支付集成-申请...
  • 最近在网上看到一些小站有微信零钱金额生成和支付宝资产生成的功能,感觉娱乐性挺...因此可以在微信零钱余额位置即时显示出我们输入的数值。 然而真正实现,是通过一个隐藏的canvas,将原始图片渲染到canvas中,然后再
  • (十五) 支付管理:支付宝支付,微信支付、银联支付、货到付款、积分支付、余额支付 (十六) 短信接口:中国网建、阿里大于 (十七) 登录接口:QQ登录、微信登录、微博登录 (十八) 物流接口:快递100接口 (十九) 其他...
  • 商城商品微信支付

    2017-07-12 18:01:00
    1.当我们自己有微信公众号,开通了微信支付业务 2.我们到微信支付的官 网,https://pay.weixin.qq.com/wiki/doc/api/index.html 公众号支付的开发文档 image.png 3.首先我们需要下载sdk imag...
  • 技术:spirngboot+微信扫码支付模式二+google生成二维码+html+jquery+mevan+热部署 运行环境:eclipse/idea+java jdk 1.8+
  • springboot集成微信支付

    千次阅读 2019-08-18 17:54:28
    一、先去微信申请相应的appid等,然后在yml文件增加相应配置 pay: wxpay: appID: ****** mchID: ***** key: ***** notifyUrl: ***** appSecret: ***** 建立配置类: @ConfigurationProperties(prefix = ...
  • 微信支付现金红包接口 原文:微信支付现金红包接口微信支付现金红包接口正式开放,只需开通微信支付,即可接入现金红包。通过现金红包接口,公众号开发者可以策划相关运营活动,向用户发放微信支付现金...
  • 个人如何接入支付宝或者微信支付等支付接口

    万次阅读 热门讨论 2020-03-06 11:07:28
    除了打造和维护一个资质足够高的企业去向微信或者支付宝请求合作认证,还有其它能得到支付接口的途径吗? …… 首先…… 接下来修改php文件中的accountID和accountKey,直接调用那个php函数 就可以通过支付接口发起...
  • 那是商家申请了微信支付商家收款码和支付宝商家收款码,并且进行了合并,所以展示的就是一个二维码,实际上微信和支付宝都可以扫码付款。所以作为商家,其实只要把微信和支付宝这两种支付方式合并了,那么其实几...
  • 微信支付全流程对接文档

    千次阅读 2019-05-07 09:09:58
    微信支付全流程对接文档 第一部分:诊中支付 1.1.1患者信息查询 请求地址 注意 诊疗卡类型必须支持身份证和院内诊疗卡两种(patCardType = 1或5); 当诊疗卡类型为...
  • 春节期间,微信红包以其独特的魅力,优秀的用户体验和安全的支付环境,一经推出即受到了广大用户的热烈欢迎,现微信支付现金红包向微信支付商户开发,具体能力如下: 1、商户调用接口时,通过指定发送对象以及发送...
  • 配置类与工具类1.1 okhttp3工具类1.2 微信支付配置类1.3 微信支付工具类2. 获取平台证书与图片上传接口3. 参考链接 1. 配置类与工具类 引入gradle依赖 subprojects { dependencies { ... //微信的apache-...
  • thinkphp5 的微信支付整合

    千次阅读 2017-11-27 16:53:35
    下载地址:链接: https://pan.baidu.com/s/1eRUkvtC 密码: eu98 ... 下载后直接解压至extend目录下 然后去公共函数库common写一个函数: ...//微信支付函数 function wxpay($body,$total_fee,$out_trade
  • 只有企业资质才能申请微信支付宝接口,要想实现自动收款除了想办法搞到企业资质申请官方的微信支付接口外,还可以想办法通过个人收款码来实现。   1.上传个人微信支付宝收款码       1.1 要是固定...
  • 支付宝和微信支付的各种坑

    千次阅读 2017-02-17 18:54:45
    截图如下,由于公司同时接入支付宝和微信支付,所以导入的库就多了点咯: 9CCA6D99-B122-4C6E-8A1D-522BC3292A4E.png 问题5.Redefinition of ‘RSA’ as different kind of symbol 多为sdk集成时产生的坑...
  • Python实现微信支付(三种方式)

    万次阅读 多人点赞 2018-10-23 19:04:08
    Python实现微信支付(三种方式) 一、准备环境 ###1、要有微信公众号,商户平台账号 https://pay.weixin.qq.com/wiki/doc/api/index.html 2、支持的支付方式有 3、备案域名 选择扫码支付,如果使用模式二则...
  • (十五) 支付管理:支付宝支付,微信支付、银联支付、货到付款、积分支付、余额支付 (十六) 短信接口:中国网建、阿里大于、阿里云-云通信、短信宝 (十七) 登录接口:QQ登录、微信登录、微博登录、支付宝登录 (十八) ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,060
精华内容 424
关键字:

微信支付余额图片