Heim  >  Artikel  >  WeChat-Applet  >  Detaillierte Einführung in den Entwicklungsprozess von WeChat Pay

Detaillierte Einführung in den Entwicklungsprozess von WeChat Pay

高洛峰
高洛峰Original
2017-03-15 17:33:371993Durchsuche

In diesem Artikel werden hauptsächlich relevante Informationen zum Entwicklungsprozess der WeChat-Zahlung vorgestellt. Freunde, die sie benötigen, können darauf verweisen.

Beachten Sie, dass ich die offene Zahlungsplattform WeChat verwende, die mit der mobilen App zusammenhängt nicht für die Öffentlichkeit. Das Konto ist irrelevant.

Der Hauptvorgang der WeChat-Zahlung

1 Der Benutzer durchsucht die App, wählt das Produkt aus und gibt eine Bestellung auf.

2. Der Server verarbeitet die Bestelllogik und startet den formellen Zahlungsvorgang

3. Zunächst initiiert der Backend-Server eine Anfrage an den Weixin-Server, um einen Token zu erhalten.

4. Der Backend-Server ruft das Token ab, verschlüsselt es mit anderen Parametern und sendet erneut eine Anfrage an den Weixin-Server, um eine Vorauszahlungs-ID zu erhalten.

5. Der Backend-Server sendet die Prepaid-ID an der App-Client

6. Die App ruft die WeChat--Steuerung auf dem Telefon auf, um den Zahlungsvorgang abzuschließen.

7.app initiiert eine Rückrufanforderung an den Backend-Server, um den Server darüber zu informieren, dass die Transaktion abgeschlossen ist.

8. Nachdem der Weixin-Server alle Prozesse verarbeitet hat, initiiert er eine Post-Anfrage an den Backend-Server, um den Backend-Server offiziell darüber zu informieren, dass die Transaktion abgeschlossen ist

Einige der oben genannten Prozesse Hinweis:

1. Der jedes Mal erhaltene Token ist zeitlich begrenzt, der Standardwert beträgt 7200 Sekunden und kann bis zu 200 Mal am Tag abgerufen werden Legen Sie es am besten in den RedisCache und rufen Sie es nach Ablauf erneut ab

2 Der von der App initiierte Rückruf ist standardmäßig unzuverlässig Es ist am besten (aber nicht unbedingt), eine Bestellung Abfrage an den WeChat-Server zu initiieren und die Ergebnisse dieser Transaktion zu überprüfen.

3. Das vom Weixin-Server initiierte Nichtwenny im Hintergrund ist die letzte Barriere, um den Abschluss der Transaktion sicherzustellen. Der Hintergrundserver muss nach der Bestätigung „Erfolg“ zurückgeben, andernfalls versucht der Weixin-Server, die Anfrage erneut zu senden.

Token abrufen

Dieser Schritt ist sehr einfach, senden Sie einfach eine Get-Anfrage. Konfigurieren Sie einfach die richtigen Parameter.

‘‘‘从微信服务器获取token‘‘‘
  def _getAccessTokenFromWeixin(self):
    response = requests.get(self.tokenUrl % (self.appId, self.appSecret))
    if response.status_code == 200:
      text = response.text
      tokenInfo = json.loads(text)
      try:
        token = tokenInfo[‘access_token‘]
        expires_in = tokenInfo[‘expires_in‘]
        self._writeWeixinTokenLog(token, self.order_no)
        return token
      except KeyError:
        return None #token获取失败
    return None #http请求失败

Prepaidid erhalten

Im Entwicklungsprozess der WeChat-Zahlung ist es am mühsamsten, etwas zu bekommen Prepaid.

In diesem Schritt müssen wir einen solchen Parameter zusammenstellen:

{
"appid":"wxd930ea5d5a258f4f",
"traceid":"test_1399514976",
"noncestr":"e7d161ac8d8a76529d39d9f5b4249ccb ",
"timestamp":1399514976, "package":"bank_type=WX&body=%E6%94%AF%E4%BB%98%E6%B5%8B%E8%AF%
95&fee_type=1&input_charset=UTF-8&notify_url=http%3A%2F%2Fweixin.qq.com&out_trade_ no=7240b65810859cbf2a8d9f76a638c0a3&partner=1900000109&spbill_create_ip=196.168.1.1& total_fee=1&sign=7F77B507B755B3262884291517E380F8",
"sign_method":"sha1", "app_signature":"7f77b507b755b3262884291517e380f8"
}

Paket zusammenstellen

Der erste Schritt hier besteht darin, das Paket zusammenzustellen:

"package":"bank_type=WX&body=%E6%94%AF%E4%BB%98%E6%B5%8B%E8%AF%
95&fee_type=1&input_charset=UTF-8&notify_url=http%3A%2F%2Fweixin.qq.com&out_trade_ no=7240b65810859cbf2a8d9f76a638c0a3&partner=1900000109&spbill_create_ip=196.168.1.1& total_fee=1&sign=7F77B507B755B3262884291517E380F8",

Die zum Zusammenbau des Pakets erforderlichen Parameter sind wie im obigen Code gezeigt, also wir Sie müssen einen Parameter vorbereiten und dann eine Signatur vorbereiten. Der Signaturvorgang ist wie folgt:

1. Sortieren Sie die Parameter entsprechend der Wörterbuchreihenfolge des Schlüssels und fügen Sie sie dann zu String zusammen . Beachten Sie, dass diese Schlüssel kein Zeichen

2 enthalten. Splice key=paternerKey nach der obigen Zeichenfolge, führen Sie dann eine md5-Signatur für die gesamte Zeichenfolge aus und konvertieren Sie sie dann in Großbuchstaben Mal bekommen wir die Signatur

und dann werden wir alle params Der Wert wird urlencodiert und dann mit sign=signValue gespleißt, um die Paketzeichenfolge zu erhalten.

Der Prozess zum Erstellen von MD5 ist hier wie folgt:

def createMD5Signature(self, signParams):
    ‘‘‘先排序‘‘‘
    sortedParams = sorted(signParams.iteritems(), key=lambda d:d[0])
    ‘‘‘拼接‘‘‘  
    stringSignTemp = "&".join(["%s=%s" % (item[0], item[1]) for item in sortedParams if item[0] != ‘sign‘ and ‘‘ != item[1]])
    #加上财付通商户权限密钥
    stringSignTemp += ‘&key=%s‘ % (self.partnerKey)
    #使用MD5进行签名,然后转化为大写
    stringSign = hashlib.md5(stringSignTemp).hexdigest().upper()  #Upper
    return stringSign

Der Code zum Zusammenstellen des Pakets:

def getPackage(self, packageParams):
    ‘‘‘先获取params的sign,然后将params进行urlencode,最后拼接,加上sign‘‘‘
    sign = self.createMD5Signature(packageParams)
    packageParams = sorted(packageParams.iteritems(), key=lambda d:d[0])
    stringParams = "&".join(["%s=%s" % (item[0], urllib.quote(str(item[1]))) for item in packageParams])
    stringParams += ‘&sign=%s‘ % (sign)
    return stringParams

Fahren Sie mit der Zusammenstellung der Parameter fort

Nach Erhalt des Pakets fahren wir mit der Zusammenstellung der Parameter fort:

Die hier erforderlichen Parameter sind:

appid=wxd930ea5d5a258f4f
appkey=L8LrMqqeGRxST5reouB0K66CaY A WpqhA Vsq7ggKkxHCOastWksvuX1uvmvQcl xaHoYd3ElNBrNO2DHnnzgfVG9Qs473M3DTOZug5er46FhuGofumV8H2FVR9qkjSlC5K
noncestr=e7d161ac8d8a76529d39d9f5b4249ccb
package=bank_type=WX&body=%E6%94%AF%E4%BB%98%E6%B5%8B%E8%AF%95 &fee_type=1&input_charset=UTF-8&notify_url=http%3A%2F%2Fweixin.qq.com&out_trade_no =7240b65810859cbf2a8d9f76a638c0a3&partner=1900000109&spbill_create_ip=196.168.1.1&tot al_fee=1&sign=7F77B507B755B3262884291517E380F8
timestamp=1399514976

traceid=test_1399514976

Beachten Sie, dass es hier eine Grube gibt:

Die oben genannten Parameter sind an der Signatur beteiligt, aber der letzte Parameter enthält nicht appKey. Denken Sie daran, nach dem Signieren zu löschen .

1. Sortieren Sie alle Parameter in lexikografischer Reihenfolge und verbinden Sie sie dann

2. Signieren Sie die sha1-Signatur und fügen Sie sie an das Ende der obigen Zeichenfolge an

3. Beachten Sie Folgendes: Löschen Sie den appKey und fügen Sie dann ein Zeichen hinzu.

Der Code zum Erhalten der SHA1-Signatur lautet wie folgt:

def createSHA1Signature(self, params):
    ‘‘‘先排序,然后拼接‘‘‘
    sortedParams = sorted(params.iteritems(), key=lambda d:d[0]) 
    stringSignTemp = "&".join(["%s=%s" % (item[0], item[1]) for item in sortedParams])
    stringSign = hashlib.sha1(stringSignTemp).hexdigest()
    return stringSign

Dann erhalten wir Parameter wie diese:

{
"appid":"wxd930ea5d5a258f4f", 
"noncestr":"e7d161ac8d8a76529d39d9f5b4249ccb", 
"package":"Sign=WXpay";
"partnerid":"1900000109" 
"prepayid":"1101000000140429eb40476f8896f4c9", 
"sign":"7ffecb600d7157c5aa49810d2d8f28bc2811827b", 
"timestamp":"1399514976"
}

Prepaidid erhalten

Der Code lautet wie folgt:

‘‘‘获取预支付prepayid‘‘‘
  def gerPrepayId(self, token, requestParams):
    ‘‘‘将参数,包括package,进行json化,然后发起post请求‘‘‘
    data = json.dumps(requestParams)
    response = requests.post(self.gateUrl % (token), data=data)
    if response.status_code == 200:
      text = response.text
      text = json.loads(text)
      errcode = text[‘errcode‘]
      if errcode == 0:
        return text[‘prepayid‘]
    return None

Das Prepayid-Format, das wir erhalten, sollte wie folgt aussehen:

{"prepayid":"1101000000140429eb40476f8896f4c9","errcode":0,"errmsg" :"Erfolg"}

Erneut signieren

Hier verwenden wir die obige sha1-Signaturmethode, um erneut zu signieren, und erhalten die folgenden Parameter:

{
"appid":"wxd930ea5d5a258f4f", 
"noncestr":"e7d161ac8d8a76529d39d9f5b4249ccb", 
"package":"Sign=WXpay";
"partnerid":"1900000109" 
"prepayid":"1101000000140429eb40476f8896f4c9", 
"sign":"7ffecb600d7157c5aa49810d2d8f28bc2811827b", 
"timestamp":"1399514976"
}

Der Hintergrundserver gibt das Ergebnis an die App zurück und die App kann die Zahlung veranlassen.

Der obige Prozesscode lautet:

‘‘‘接收app的请求,返回prepayid‘‘‘
class WeixinRequirePrePaidHandler(BasicTemplateHandler):

  ‘‘‘这个方法在OrdersAddHandler中被调用‘‘‘
  @staticmethod
  def getPrePaidResult(order_no, total_pay, product_name, client_ip):
    ‘‘‘封装了常用的签名算法‘‘‘
    weixinRequestHandler = WeixinRequestHandler(order_no)
    ‘‘‘收集订单相关信息‘‘‘
    addtion = str(random.randint(10, 100)) #产生一个两位的数字,拼接在订单号的后面
    out_trade_no = str(order_no) + addtion
    order_price = float(total_pay) #这里必须允许浮点数,后面转化成分之后转化为int
    #order_price = 0.01 #测试
    remote_addr = client_ip #客户端的IP地址
    print remote_addr
    current_time = int(time.time())
    order_create_time = str(current_time)
    order_deadline = str(current_time + 20*60)

    ‘‘‘这里的一些参数供下面使用‘‘‘
    noncestr = hashlib.md5(str(random.random())).hexdigest()
    timestamp = str(int(time.time()))
    pack = ‘Sign=WXPay‘

    ‘‘‘获取token‘‘‘
    access_token = weixinRequestHandler.getAccessToken()
    logging.info("get token: %s" % access_token)
    if access_token:
      ‘‘‘设置package参数‘‘‘
      packageParams = {}
      packageParams[‘bank_type‘] = ‘WX‘  #支付类型
      packageParams[‘body‘] = product_name #商品名称
      packageParams[‘fee_type‘] = ‘1‘   #人民币 fen
      packageParams[‘input_charset‘] = ‘GBK‘ #GBK
      packageParams[‘notify_url‘] = config[‘notify_url‘] #post异步消息通知
      packageParams[‘out_trade_no‘] = str(out_trade_no) #订单号
      packageParams[‘partner‘] = config[‘partnerId‘] #商户号
      packageParams[‘total_fee‘] = str(int(order_price*100))  #订单金额,单位是分
      packageParams[‘spbill_create_ip‘] = remote_addr #IP
      packageParams[‘time_start‘] = order_create_time #订单生成时间
      packageParams[‘time_expire‘] = order_deadline #订单失效时间

      ‘‘‘获取package‘‘‘
      package = weixinRequestHandler.getPackage(packageParams)

      ‘‘‘设置支付参数‘‘‘
      signParams = {}
      signParams[‘appid‘] = config[‘appId‘]
      signParams[‘appkey‘] = config[‘paySignKey‘] #delete
      signParams[‘noncestr‘] = noncestr
      signParams[‘package‘] = package
      signParams[‘timestamp‘] = timestamp
      signParams[‘traceid‘] = ‘mytraceid_001‘

      ‘‘‘生成支付签名‘‘‘
      app_signature = weixinRequestHandler.createSHA1Signature(signParams)
      ‘‘‘增加不参与签名的额外参数‘‘‘
      signParams[‘sign_method‘] = ‘sha1‘
      signParams[‘app_signature‘] = app_signature

      ‘‘‘剔除appKey‘‘‘
      del signParams[‘appkey‘]

      ‘‘‘获取prepayid‘‘‘
      prepayid = weixinRequestHandler.gerPrepayId(access_token, signParams)
      if prepayid:

        ‘‘‘使用拿到的prepayid再次准备签名‘‘‘
        pack = ‘sign=WXPay‘
        prepayParams = {}
        prepayParams[‘appid‘] = config[‘appId‘]
        prepayParams[‘appkey‘] = config[‘paySignKey‘]
        prepayParams[‘noncestr‘] = noncestr
        prepayParams[‘package‘] = pack
        prepayParams[‘partnerid‘] = config[‘partnerId‘]
        prepayParams[‘prepayid‘] = prepayid
        prepayParams[‘timestamp‘] = timestamp

        ‘‘‘生成签名‘‘‘
        sign = weixinRequestHandler.createSHA1Signature(prepayParams)

        ‘‘‘准备输出参数‘‘‘
        returnParams = {}
        returnParams[‘status‘] = 0
        returnParams[‘retmsg‘] = ‘success‘
        returnParams[‘appid‘] = config[‘appId‘]
        returnParams[‘noncestr‘] = noncestr
        returnParams[‘package‘] = pack
        returnParams[‘prepayid‘] = prepayid
        returnParams[‘timestamp‘] = timestamp
        returnParams[‘sign‘] = sign
        returnParams[‘partnerId‘] = config[‘partnerId‘]
        returnParams[‘addtion‘] = addtion
        
      else:
        ‘‘‘prepayid获取失败‘‘‘
        returnParams = {}
        returnParams[‘status‘] = -1
        returnParams[‘retmsg‘] = ‘prepayid获取失败‘
    else: 
      ‘‘‘token获取失败‘‘‘
      returnParams = {}
      returnParams[‘status‘] = -1
      returnParams[‘retmsg‘] = ‘token获取失败‘

    ‘‘‘生成json格式文本,然后返回给APP‘‘‘
    return returnParams

Asynchrone Hintergrundbenachrichtigung

WeChat-Server Die gesendete asynchrone Benachrichtigung ist das letzte Zeichen für eine erfolgreiche Zahlung. Dieser Schritt ist Sicherheit. Aus Sicherheitsgründen müssen wir die Signatur erweitern:

Der Erweiterungscode lautet wie folgt:

def isTenpaySign(self, params):
    helper = WeixinRequestHandler()
    sign = helper.createMD5Signature(params)
    return params[‘sign‘] == sign

Der Gesamtprozess ist wie folgt:

‘‘‘微信服务器向后台发送的异步通知‘‘‘
class WeixinAppNotifyHandler(BasicTemplateHandler):
  def initialize(self):
    self.weixinResponseHandler = WeixinResponseHandler()

  def post(self):
    ‘‘‘解析参数‘‘‘
    params = self.parseQueryString()

    ‘‘‘验证是否是weixin服务器发回的消息‘‘‘
    verifyWeixinSign = self.weixinResponseHandler.isTenpaySign(params)
    ‘‘‘处理订单‘‘‘
    if verifyWeixinSign:
      ‘‘‘订单逻辑‘‘‘
      order_no = str(params[‘out_trade_no‘])
      order_no = order_no[0:-2]
      print ‘%s paied successfully‘ % order_no
      self.saveWeixinReceipt(params)
      updateOrdersPaidByWeixin(order_no) #更新订单使用状态
      consumeCouponByOrderNo(order_no) #优惠券已经使用
      self.write("success")
    else:
      self.write("fail")

  def parseQueryString(self):
    ‘‘‘获取url中所有的参数‘‘‘
    uri = self.request.uri
    ‘‘‘解析出URI中的query字符串‘‘‘
    parseResult = urlparse.urlparse(uri) 
    query = parseResult.query
    ‘‘‘解析query字符串‘‘‘
    params = urlparse.parse_qs(query)
    for item in params:
      params[item] = params[item][0].strip()
    return params

Schließlich gilt die Zahlung als nicht erfolgreich, wenn der Benutzer die Zahlung auf dem Mobiltelefon abschließt. Erst wenn der Weixin-Server den durch die Benachrichtigung zurückgegebenen Erfolg erhält, gilt die Transaktion zu diesem Zeitpunkt endgültig als erfolgreich kann die offizielle WeChat-Nachricht empfangen.

Das Obige ist eine Zusammenstellung von Informationen zum WeChat-Zahlungsentwicklungsprozess. Wir werden auch in Zukunft relevante Informationen hinzufügen. Vielen Dank für Ihre Unterstützung dieser Website.

Das obige ist der detaillierte Inhalt vonDetaillierte Einführung in den Entwicklungsprozess von WeChat Pay. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn