cocos2d-js android django微信支付

APP微信支付

APP支付流程

1. 使用django生成预支付订单

wxpay.py


import hashlib
import time
from urllib.parse import quote

import requests
import xmltodict

from pay import settings

class WeiXinPay(object):
    def __init__(self):
        self.APPID = settings.WX_APPID
        self.MCHID = settings.WXPAY_MCHID
        self.NOTIFY_URL = 'https://****/weixin_notify/'
        self.TRADE_TYPE = 'APP'
        self.APIKEY = settings.WXPAY_APIKEY
        self.url = 'https://api.mch.weixin.qq.com/pay/unifiedorder'
        self.error = None
        self.params = None

    def get_parameter(self, order_id, body, total_fee, spbill_create_ip):
        self.params = {
            'appid': self.APPID,
            'mch_id': self.MCHID,
            'nonce_str': self.getNonceStr(),
            'body': body,
            'out_trade_no': str(order_id),
            'total_fee': str(int(total_fee)),
            'spbill_create_ip': spbill_create_ip,
            'trade_type': self.TRADE_TYPE,
            'notify_url': self.NOTIFY_URL,
        }
        return self.params

    def getNonceStr(self, length=32):
        """生成随机字符串"""
        import random
        chars = "abcdefghijklmnopqrstuvwxyz0123456789"
        strs = []
        for x in range(length):
            strs.append(chars[random.randrange(0, len(chars))])
        return "".join(strs)

    def key_value_url(self, value, urlencode):
"""
        将键值对转为 key1=value1&key2=value2
        对参数按照key=value的格式,并按照参数名ASCII字典序排序
"""
        slist = sorted(value)
        buff = []
        for k in slist:
            v = quote(value[k]) if urlencode else value[k]
            buff.append("{0}={1}".format(k, v))

        return "&".join(buff)

    def get_sign(self, params):
"""
        生成sign
        拼接API密钥
"""
        stringA = self.key_value_url(params, False)
        stringSignTemp = stringA + '&key=' + self.APIKEY
        sign = (hashlib.md5(stringSignTemp.encode("utf-8")).hexdigest()).upper()
        params['sign'] = sign
        return params

    def get_req_xml(self):
"""
        拼接XML
"""
        self.get_sign(self.params)
        xml = ""
        for k, v in self.params.items():
            xml += ' + k + '>' + v + ' + k + '>'
        xml += ""
        return xml.encode("utf-8")

    def get_prepay_id(self):
"""
        请求获取prepay_id
"""
        xml = self.get_req_xml()
        respone = requests.post(self.url, xml, headers={'Content-Type': 'application/xml'})
        msg = respone.text.encode('ISO-8859-1').decode('utf-8')
        xmlresp = xmltodict.parse(msg)
        if xmlresp['xml']['return_code'] == 'SUCCESS':
            if xmlresp['xml']['result_code'] == 'SUCCESS':
                prepay_id = xmlresp['xml']['prepay_id']
                self.params['prepay_id'] = prepay_id
                self.params['package'] = "Sign=WXPay"
                self.params['timestamp'] = str(int(time.time()))
                return self.params
            else:
                return 'failure'
        else:
            return 'failure'

    def re_finall(self):
        """得到prepay_id后再次签名,返回给终端参数
"""
        self.get_prepay_id()
        if self.error:
            return
        sign_again_params = {
            'appid': self.params['appid'],
            'noncestr': self.params['nonce_str'],
            'package': self.params['package'],
            'partnerid': self.params['mch_id'],
            'timestamp': self.params['timestamp'],
            'prepayid': self.params['prepay_id']
        }
        self.get_sign(sign_again_params)
        sign_again_params['sign'] = sign_again_params['sign']
        return sign_again_params

    def get_notifypay(self, data):
        dictdata = dict(data)
        _dictdata = dict(dictdata['xml'])
        success = self.get_sign(_dictdata)
        if success:
            success.pop("sign", None)
            success.pop("sign_type", None)
            return success
        else:
            return None

    @staticmethod
    def xml_to_dict(params):
"""
        拼接XML
"""
        if not isinstance(params, dict):
            return None
        xml = ""
        for k, v in params.items():

            xml += ' + k + '>' + v + ' + k + '>'
        xml += ""
        return xml

views.py

import random

import arrow
from rest_framework.response import Response
from rest_framework.views import APIView

from pay.wxpay import WeiXinPay

class Payment(APIView):
    def order_number(self):
        num = random.randint(100000,999999)
        order_id = str(arrow.now().timestamp) + str(num)
        return order_id

    def post(self,request):
        total_fee = int(request.data.get('total_fee',201))
        body = '支付TEST'
        spbill_create_ip = '127.0.0.1'
        order_id = self.order_number()
        pay = WeiXinPay()
        parameter_dict = pay.get_parameter(order_id, body, total_fee, spbill_create_ip)
        response = pay.re_finall()
        return Response(response)

url.py

path('payment/', Payment.as_view()),

cocos2d-js 拉起生成预订单

封装http请求


function httpPostTest(url, data, callback) {
    var url = 'http://39.108.86.11/' + url;
    var xhr = new XMLHttpRequest();
    xhr.responseType = "text";
    xhr.open('POST', url);

    let token = jsb.reflection.callStaticMethod("com/tf/y/utils/SPUtil", "getStr", "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;", "token", "None");

    xhr.setRequestHeader("Authorization", "Bearer" + " " + token);
    xhr.setRequestHeader("Content-Type", "application/json");

    xhr.send(JSON.stringify(data));

    xhr.onload = function(e) {};
    xhr.onreadystatechange = function(e) {
        if (xhr.readyState == 4 && xhr.status == 200) {
            var xhrRes = (new Function("return " + xhr.responseText))();
            callback(xhrRes);
        }
    };
};

Weixinpay.js

function weixinpay() {
    data = {'total_fee':201}
    httpPostTest('payment/', data, function(res) {

        cc.log('============pay========',JSON.stringify(res))

        jsb.reflection.callStaticMethod("com/tf/y/AppActivity", "WeiXinPay", "(Ljava/lang/String;)V",JSON.stringify(res))
    })
}

Android 拉起微信支付

导入微信sdk以及阿里fastjson

dependencies{
    ···
    ···
    compile 'com.tencent.mm.opensdk:wechat-sdk-android-with-mta:+'
    compile 'com.alibaba:fastjson:1.2.54'
}

AppActivity.java


package com.tf.y;

import android.util.Log;
import org.cocos2dx.lib.Cocos2dxActivity;
import org.cocos2dx.lib.Cocos2dxGLSurfaceView;
import org.cocos2dx.lib.Cocos2dxJavascriptJavaBridge;
import com.tencent.mm.opensdk.openapi.IWXAPI;
import com.alibaba.fastjson.JSONObject;

import java.util.Timer;
import java.util.TimerTask;

public class AppActivity extends Cocos2dxActivity {
    private static String APPID = "";
    public static IWXAPI api;

    ···

    public static void WeiXinPay(String str){
        Log.d("pay","开启微信支付");
        api = WXAPIFactory.createWXAPI(getActivity(),APPID,true);
        PayReq request = new PayReq();

        JSONObject jsonObject = JSONObject.parseObject(str);

        api.registerApp(APPID);
        request.appId = jsonObject.getString("appid");
        request.partnerId = jsonObject.getString("partnerid");
        request.prepayId= jsonObject.getString("prepayid");
        request.packageValue = "Sign=WXPay";
        request.nonceStr= jsonObject.getString("noncestr");
        request.timeStamp= jsonObject.getString("timestamp");
        request.sign= jsonObject.getString("sign");
        api.sendReq(request);
    }

    public static void callJsWxPAy(final int value){

        final String exes = "paymentResult('"+ value + "')";
        TimerTask task = new TimerTask(){
            public void run(){

                Cocos2dxGLSurfaceView.getInstance().queueEvent(new Runnable() {
                    @Override
                    public void run() {
                        Cocos2dxJavascriptJavaBridge.evalString("cc.log('微信调取js----java log')");
                        Cocos2dxJavascriptJavaBridge.evalString(exes);
                    }
                });
            }
        };
        Timer timer = new Timer();
        timer.schedule(task, 100);

    }

}

WXPayEntryActivity.java


package com.tf.y.wxapi;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;

import com.tencent.mm.opensdk.constants.ConstantsAPI;
import com.tencent.mm.opensdk.modelbase.BaseReq;
import com.tencent.mm.opensdk.modelbase.BaseResp;
import com.tencent.mm.opensdk.openapi.IWXAPI;
import com.tencent.mm.opensdk.modelmsg.SendAuth;
import com.tencent.mm.opensdk.openapi.IWXAPIEventHandler;
import com.tencent.mm.opensdk.openapi.WXAPIFactory;
import com.tf.y.AppActivity;

public class WXPayEntryActivity extends Activity implements IWXAPIEventHandler {
    private IWXAPI wxAPI;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        wxAPI = WXAPIFactory.createWXAPI(this, "");
        wxAPI.handleIntent(getIntent(), this);
    }

    @Override
    protected void onNewIntent(Intent intent){
        super.onNewIntent(intent);
        setIntent(intent);
        wxAPI.handleIntent(intent, this);
    }

    @Override
    public void onReq(BaseReq baseReq) {}

    @Override
    public void onResp(BaseResp baseRes) {
        Log.i("ansen", "微信支付回调 返回错误码:"+baseRes.errCode+" 错误名称:"+baseRes.errStr);

        AppActivity.callJsWxPAy(baseRes.errCode);
        finish();
    }
}

AndroidManifest.xml

        <activity
            android:name="com.tf.y.wxapi.WXPayEntryActivity"
            android:exported="true"
            android:launchMode="singleTop">

            <intent-filter>
                <action android:name="android.intent.action.VIEW"/>
                <category android:name="android.intent.category.DEFAULT"/>
                <data android:scheme=""/>
            </intent-filter>

        </activity>

支付成功django回调


from django.http import HttpResponse, JsonResponse
from rest_framework.views import APIView
import xml.etree.ElementTree as et

class WxpayNotify(APIView):
    def post(self,request):
        _xml = request.body
        xml = str(_xml, encoding="utf-8")
        tree = et.fromstring(xml)
        return_code = tree.find("return_code").text
        err_resp = ""
        success_resp = ""

        if return_code == 'FAIL':
            return HttpResponse(err_resp, content_type='text/xml', status=200)

        elif return_code == 'SUCCESS':
            order_id = tree.find("out_trade_no").text
            wx_order = tree.find("transaction_id").text
            time_end = tree.find("time_end").text

            return HttpResponse(success_resp, content_type='text/xml', status=200)

url.py

path('weixin_notify/', WxpayNotify.as_view()),

Original: https://blog.csdn.net/m0_47202787/article/details/120344310
Author: Ang-l
Title: cocos2d-js android django微信支付



相关阅读

Title: python教程:一篇文章让你理解字符串的格式化

有这样一个字符串:

sg = """
"""

如果我们希望用户输入姓名、年龄、性别和爱好,程序将以上述格式打印出来。从我们目前所了解的情况来看,我们可以使用此代码来实现:

[En]

If we want the user to enter a name, age, gender and hobby, then the program will print it out in the above format. From what we have learned so far, we can use this code to achieve:

a = "------info------"
b = "name: "
c = "age: "
d = "sex: "
e = "hobby: "
f = "-------end------"
name = input(b)
age = input(c)
sex = input(d)
hobby = input(e)
print(a)
print(b + name)
print(c + age)
print(d + sex)
print(e + hobby)
print(f)

代码运行后就是这样的:

name: alex
age: 18
sex: 男
hobby: 女

但是,虽然我们已经实现了需求,但它太繁琐了。这里可以使用格式化方法。格式化是将占位符放在需要自定义它的字符串中,然后通过向占位符提供数据来构建新的字符串。提供的数据需要与占位符对应,否则将报告错误。

[En]

But although we have achieved the demand, it is too cumbersome. The formatting method can be used here. Formatting is to put a placeholder in a string where you need to customize it, and then build a new string by providing data to the placeholder. The data provided needs to correspond to the placeholder, otherwise an error will be reported.

Python中常用的占位符有:

  • %s 字符串:%s 可以填充字符串也可以填充数字(其实也可以是其他数据类型)
  • %d | %i 整型:必须填充数字
  • %% 转义:变成普通的 %

有了格式化的方法,上面的例子我们就可以简化成这个样子:

name = input("name: ")
age = input("age: ")
sex = input("sex: ")
hobby = input("hobby: ")
a = "哈哈啊"
msg = """
"""
print(msg % (name, int(age), sex, hobby))

在 Python 3.6 及以后的版本中引入了一个新的 f-strings 方法格式字符串,把上面的格式化方法进一步简化,具体做法为:

msg = f"""
"""
print(msg)

在字符串的引号前,用小写字母 f 声明字符串为 f-strings 格式的字符串。用大括号将需要格式化的位置标记出来,在大括号里面填入变量或者数据,构建成新的字符串。

可以通过两个大括号来进行转义,表示普通的大括号:

{{ }}

.format() 方法是另外一种字符串格式化的方法:

'''
学习中遇到问题没人解答?小编创建了一个Python学习交流群:857662006
寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
'''
s = 'alex{}wu{}si{}r'
s1 = s.format('你好', '我好', '大家好')
print(s1)

输出的结果为:alex你好wu我好si大家好r

.format() 方法除了向上面这种按照位置格式化之外,还可以按照索引格式化:

s = 'alex{0}wu{2}si{1}r'
s1 = s.format('你好', '我好', '大家好')
print(s1)

输出的结果为:alex你好wu大家好si我好r

.format() 方法还可以按照关键字进行格式化:

s = 'alex{a}wu{c}si{b}r'
s1 = s.format(b = '你好', a = '我好', c = '大家好')
print(s1)

输出的结果为:alex我好wu大家好si你好r

Original: https://www.cnblogs.com/xxpythonxx/p/16093823.html
Author: python学习者0
Title: python教程:一篇文章让你理解字符串的格式化

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/290789/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

最近整理资源【免费获取】:   👉 程序员最新必读书单  | 👏 互联网各方向面试题下载 | ✌️计算机核心资源汇总