1. 程式人生 > >5.微信支付之統一下單

5.微信支付之統一下單

統一下單

除刷卡支付場景以外,商戶系統先呼叫該介面在微信支付服務後臺生成預支付交易單,返回正確的預支付交易回話標識後再按掃碼、JSAPI、APP等不同場景生成交易串調起支付。

統一下單時除了被掃支付之外的其他支付方式必須要進行的操作

使用場景

  • 掃碼支付模式1,模式2

  • JSAPI 支付

  • APP支付

統一下單介面

https://api.mch.weixin.qq.com/pay/unifiedorder,package config中定義為URL_UNIFIEDORDER
  • 資料提交方式為post方式

  • 資料格式為xml格式

商戶側流程

商戶在實現掃碼支付,JSAPI支付以及APP支付的時候,都必須呼叫統一下單介面來獲取prepay_id,然後再利用prepay_id根據不同的支付場景發起支付

開發實現

統一下單實現中用到了package tools裡面的微信支付簽名,網路請求,生成隨機字串,請先去實現

建立unifiedorder包

建立unifiedorder資料夾

統一下單請求

建立unifiedorderrequest.go檔案,實現:

  • Unifieldrequest結構體:儲存統一下單要使用的引數

  • func (v *Unifieldrequest) Signmd5()函式:對Unifieldreques裡面的非空欄位進行微信支付MD5簽名

  • func (v *Unifieldrequest) Xml()

    函式:將Unifieldrequest裡面的非空欄位組織為xml格式的資料

  • func (v Unifieldrequest) Dorequest() Unifiedorderreponse函式:傳送請求xml資料到統一下單介面,並返回請求結果

程式碼如下:

package unifiedorder

import (
    "encoding/xml"
    "wechatpaygolang/config"
    "wechatpaygolang/tools"
)

//1.建立Unifieldrequest結構體,存放要使用的資料,omitempty 表示該欄位選填,否則為必填
type Unifieldrequest struct {
    XMLName     xml.Name `xml:"xml"`
    Appid       string   `xml:"appid"`                 //公眾賬號ID
    Attach      string   `xml:"attach,omitempty"`      //附加資料
    Body        string   `xml:"body"`                  //商品描述
    Detail      string   `xml:"detail,omitempty"`      //商品詳情
    Device_info string   `xml:"device_info,omitempty"` //裝置號
    Fee_type    string   `xml:"fee_type,omitempty"`    //貨幣型別
    Goods_tag   string   `xml:"goods_tag,omitempty"`   //商品標記
    Mch_id      string   `xml:"mch_id"`                //商戶號
    Nonce_str   string   `xml:"nonce_str"`             //隨機字串

    Notify_url       string `xml:"notify_url"`            //通知地址
    Openid           string `xml:"openid,omitempty"`      //使用者標識
    Out_trade_no     string `xml:"out_trade_no"`          //商戶訂單號
    Product_id       string `xml:"product_id,omitempty"`  //商品ID
    Sign             string `xml:"sign"`                  //簽名
    Spbill_create_ip string `xml:"spbill_create_ip"`      //終端IP
    Time_expire      string `xml:"time_expire,omitempty"` //交易結束時間
    Time_start       string `xml:"time_start,omitempty"`  //交易起始時間
    Total_fee        string `xml:"total_fee"`             //總金額
    Trade_type       string `xml:"trade_type"`            //交易型別

    RequestXML string `xml:"-"` //存放最終請求xml串

}

//2.對Unifieldrequest裡面的非空欄位進行MD5簽名,得到簽名結構,並儲存該結果
func (v *Unifieldrequest) Signmd5() bool {
    signmd5 := tools.Wechatpay_SignMD5(*v, config.API_KEY)
    v.Sign = signmd5
    tools.PrintlnW(signmd5, false)
    return true
}

//3.將Unifieldrequest裡面的非空欄位組織為xml格式的資料
func (v *Unifieldrequest) Xml() error {

    xmlresult, err := tools.XmlEndoestruct(v)
    v.RequestXML = xmlresult
    tools.PrintlnW(xmlresult, false)
    return err

}

//4.將最終生成的xml資料傳送到統一支付介面,並把返回的結果解析到Unifiedorderreponse
func (v Unifieldrequest) Dorequest() Unifiedorderreponse {

    data := tools.Post(config.URL_UNIFIEDORDER, v.RequestXML)
    unifiedorderreponse := Unifiedorderreponse{}
    tools.XmlDecodebytes(data, &unifiedorderreponse)
    unifiedorderreponse.ReponseXML = string(data)
    return unifiedorderreponse

}

建立統一下單返回結果資料

建立檔案 unifiedorderresponse.go,儲存發起統一下單請求後的返回結果

  • Unifiedorderreponse結構體:定義返回的資料

程式碼如下

package unifiedorder

import (
    "encoding/xml"
)

//1.儲存統一下單的返回的資料
type Unifiedorderreponse struct {
    XMLName     xml.Name `xml:"xml"`
    Return_code string   `xml:"return_code"` //返回狀態碼
    Return_msg  string   `xml:"return_msg"`  //返回資訊
    //以下欄位在return_code為SUCCESS的時候有返回
    Appid        string `xml:"appid"`                  //公眾賬號ID
    Mch_id       string `xml:"mch_id"`                 //商戶號
    Device_info  string `xml:"device_info,omitempty"`  //裝置號
    Nonce_str    string `xml:"nonce_str"`              //隨機字串
    Sign         string `xml:"sign"`                   //簽名
    Result_code  string `xml:"result_code"`            //業務結果
    Err_code     string `xml:"err_code,omitempty"`     //錯誤程式碼
    Err_code_des string `xml:"err_code_des,omitempty"` //錯誤程式碼描述
    //以下欄位在return_code 和result_code都為SUCCESS的時候有返回
    Trade_type string `xml:"trade_type,omitempty"` //交易型別
    Prepay_id  string `xml:"prepay_id,omitempty"`  //預支付交易會話標識
    Code_url   string `xml:"code_url,omitempty"`   //二維碼連結

    ReponseXML string `xml:"-"` //儲存返回的xml串

}