小程序支付功能的实现策略与操作要点

why 272 2024-07-08

实现小程序支付功能的方法:首先进行前端请求支付,并在后端请求微信服务器;然后后端接受微信服务器并返回数据;接着前端发起支付;最后后端接受微信服务器回调即可。

如何实现小程序支付功能

实现小程序支付功能的方法:

1. 前端请求支付

前端请求支付,就是简单的携带支付需要的数据,例如用户标识,支付金额,支付订单 ID 等等跟你的业务逻辑有关或者跟下一步请求微信服务器支付统一下单接口需要的数据有关** 的相关数据,使用微信小程序的 wx.request( ) 去请求后端的支付接口。

2. 后端请求微信服务器

后端接收到前端发送的支付请求后,可以进行一下相关验证,例如判断一下用户有没有问题,支付金额对不对等等。在验证没什么问题,可以向微信服务器申请支付之后,后端需要使用微信规定的数据格式 去请求微信的支付统一下单接口。

在处理好所有数据后,将这些数据以 XML 格式整理并以 POST 方法发送到微信支付统一下单接口

3.后端接受微信服务器返回数据

微信服务器在接收到支付数据之后,如果数据没有问题,其会返回用于支付的相应数据,其中非常重要的是 名称为 prepay_id 的数据字段,需要将此数据返回前端,前端才能继续支付。

因此,在后端接收到微信服务器的返回数据后,需要进行相应的处理,最终返回到前端数据,后端的支付接口已经完成了接收前端支付请求,并返回了前端支付所需数据的功能。

4. 前端发起支付

前端在接收到返回数据后,使用 wx.requestPayment()来请求发起支付。此 API 需要的对象参数各项值就是我们上一步返回的各个数据。

5.后端接受微信服务器回调

前端完成支付后,微信服务器确认支付已经完成。就会向第一步中设置的回调地址发送通知。后端的接收回调接口在接收到通知后,就可以判断支付是否完成,从而决定后续动作。

确认支付后,微信服务器会根据通知result_code字段判断支付是否成功。在接受到成功的通知后,后端需要返回success数据向微信服务器告知已得到回调通知,以此完成支付流程,否则微信服务器会不停的向后端发送消息。

对比后可以发现发现,其实小程序中做支付比公众号支付要省事很多,因为不需要支付授权目录,也不需要授权域名,但是支付流程却比公众号多了一步,就是统一下单是预支付,然后需要对预支付的结果再次签名之后,才调起支付。

完整代码如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

//小程序端代码:

pay:function(){

var that=this

wx.getStorage({

key: 'openid',

success: function(res) {

wx.request({

//这里是后台的处理方法,url是自定义的,直接换成你自己的后台处理方法即可,Wx_Pay这个方法在下面写的有

//后台用的php做处理,java的可以参考方法,道理都是一样的

url: url + 'Wx_Pay',

data: {

//用户的openid

openid:res.data,

fee: that.data.totalPrice, //支付金额

details: that.data.goodsList[0].goods_name,//支付商品的名称

},

success:function(result){

if(result.data){

//out_trade_no=res.data['out_trade_no'];

wx.requestPayment({

timeStamp: result.data['timeStamp'],

nonceStr: result.data['nonceStr'],

package: result.data['package'],

signType: 'MD5',

paySign: result.data['paySign'],

'success':function(successret){

console.log('支付成功');

//获取支付用户的信息

wx.getStorage({

key: 'userInfo',

success: function (getuser) {

//加入订单表做记录

wx.request({

url: url + 'Wx_AddOrder',

data: {

uname: getuser.data.nickName,

goods: that.data.goodsList[0].goods_name,

price: that.data.totalPrice,

openid:res.data,

},

success: function (lastreturn) {

console.log("存取成功");

}

})

},

})

},'fail':function(res){

}

})

}

}

})

},

})

},

//后台

//微信支付

    public function Wx_Pay(){

        $request=Request::instance();

        $fee=$request->param('fee');

        $details=$request->param('details');//商品的详情,比如iPhone8,紫色

       // $fee = 0.01;//举例充值0.01

        $appid =        'appid';//appid

        $body =        $details;// '金邦汇商城';//'【自己填写】'

        $mch_id =       '1486742092';//'你的商户号【自己填写】'

        $nonce_str =    $this->nonce_str();//随机字符串

        $notify_url =   'https://zys.jinbh-/admin/Api/Wx_Speech';//回调的url【自己填写】';

        $openid =       $request->param('openid');//'用户的openid【自己填写】';

        $out_trade_no = $this->order_number($openid);//商户订单号

        $spbill_create_ip = '123.206.45.131';//'服务器的ip【自己填写】';

        $total_fee =    $fee*100;//因为充值金额最小是1 而且单位为分 如果是充值1元所以这里需要*100

        $trade_type = 'JSAPI';//交易类型 默认

        //这里是按照顺序的 因为下面的签名是按照顺序 排序错误 肯定出错

        $post['appid'] = $appid;

        $post['body'] = $body;

         

        $post['mch_id'] = $mch_id;

       

        $post['nonce_str'] = $nonce_str;//随机字符串

       

        $post['notify_url'] = $notify_url;

       

        $post['openid'] = $openid;

       

        $post['out_trade_no'] = $out_trade_no;

       

        $post['spbill_create_ip'] = $spbill_create_ip;//终端的ip

       

        $post['total_fee'] = $total_fee;//总金额 最低为一块钱 必须是整数

      

        $post['trade_type'] = $trade_type;

        $sign = $this->sign($post);//签名

        $post_xml = &#39;<xml>

           <appid>&#39;.$appid.&#39;</appid>

           <body>&#39;.$body.&#39;</body>

           <mch_id>&#39;.$mch_id.&#39;</mch_id>

           <nonce_str>&#39;.$nonce_str.&#39;</nonce_str>

           <notify_url>&#39;.$notify_url.&#39;</notify_url>

           <openid>&#39;.$openid.&#39;</openid>

           <out_trade_no>&#39;.$out_trade_no.&#39;</out_trade_no>

           <spbill_create_ip>&#39;.$spbill_create_ip.&#39;</spbill_create_ip>

           <total_fee>&#39;.$total_fee.&#39;</total_fee>

           <trade_type>&#39;.$trade_type.&#39;</trade_type>

           <sign>&#39;.$sign.&#39;</sign>

        </xml> &#39;;

        //统一接口prepay_id

        $url = &#39;https://api.mch.weixin.qq.com/pay/unifiedorder&#39;;

        $xml = $this->http_request($url,$post_xml);

        $array = $this->xml($xml);//全要大写

        if($array[&#39;RETURN_CODE&#39;] == &#39;SUCCESS&#39; && $array[&#39;RESULT_CODE&#39;] == &#39;SUCCESS&#39;){

            $time = time();

            $tmp=&#39;&#39;;//临时数组用于签名

            $tmp[&#39;appId&#39;] = $appid;

            $tmp[&#39;nonceStr&#39;] = $nonce_str;

            $tmp[&#39;package&#39;] = &#39;prepay_id=&#39;.$array[&#39;PREPAY_ID&#39;];

            $tmp[&#39;signType&#39;] = &#39;MD5&#39;;

            $tmp[&#39;timeStamp&#39;] = "$time";

            $data[&#39;state&#39;] = 1;

            $data[&#39;timeStamp&#39;] = "$time";//时间戳

            $data[&#39;nonceStr&#39;] = $nonce_str;//随机字符串

            $data[&#39;signType&#39;] = &#39;MD5&#39;;//签名算法,暂支持 MD5

            $data[&#39;package&#39;] = &#39;prepay_id=&#39;.$array[&#39;PREPAY_ID&#39;];//统一下单接口返回的 prepay_id 参数值,提交格式如:prepay_id=*

            $data[&#39;paySign&#39;] = $this->sign($tmp);//签名,具体签名方案参见微信公众号支付帮助文档;

            $data[&#39;out_trade_no&#39;] = $out_trade_no;

        }else{

            $data[&#39;state&#39;] = 0;

            $data[&#39;text&#39;] = "错误";

            $data[&#39;RETURN_CODE&#39;] = $array[&#39;RETURN_CODE&#39;];

            $data[&#39;RETURN_MSG&#39;] = $array[&#39;RETURN_MSG&#39;];

        }

      echo json_encode($data);

    }

//随机32位字符串

    private function nonce_str(){

        $result = &#39;&#39;;

        $str = &#39;QWERTYUIOPASDFGHJKLZXVBNMqwertyuioplkjhgfdsamnbvcxz&#39;;

        for ($i=0;$i<32;$i++){

            $result .= $str[rand(0,48)];

        }

        return $result;

    }

//生成订单号

    private function order_number($openid){

        //date(&#39;Ymd&#39;,time()).time().rand(10,99);//18位

        return md5($openid.time().rand(10,99));//32位

    }

//签名 $data要先排好顺序

    public function sign($data)

    {

        $stringA = &#39;&#39;;

        foreach ($data as $key => $value) {

            if (!$value) continue;

            if ($stringA) $stringA .= &#39;&&#39; . $key . "=" . $value;

            else $stringA = $key . "=" . $value;

        }

        $wx_key = &#39;Zhangyusheng19810318015729366660&#39;;//申请支付后有给予一个商户账号和密码,登陆后自己设置key

        $stringSignTemp = $stringA . &#39;&key=&#39; . $wx_key;//申请支付后有给予一个商户账号和密码,登陆后自己设置key

      return strtoupper(md5($stringSignTemp));

    }

//curl请求啊

        function http_request($url, $data = null, $headers = array())

        {

            $curl = curl_init();

            if (count($headers) >= 1) {

                curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);

            }

            curl_setopt($curl, CURLOPT_URL, $url);

            curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);

            curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);

            if (!empty($data)) {

                curl_setopt($curl, CURLOPT_POST, 1);

                curl_setopt($curl, CURLOPT_POSTFIELDS, $data);

            }

            curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);

            $output = curl_exec($curl);

            curl_close($curl);

            return $output;

        }

//获取xml

        private function xml($xml){

            $p = xml_parser_create();

            xml_parse_into_struct($p, $xml, $vals, $index);

            xml_parser_free($p);

            $data = "";

            foreach ($index as $key=>$value) {

                if($key == &#39;xml&#39; || $key == &#39;XML&#39;) continue;

                $tag = $vals[$value[0]][&#39;tag&#39;];

                $value = $vals[$value[0]][&#39;value&#39;];

                $data[$tag] = $value;

            }

            return $data;

        }

//微信支付结束


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:如何在学习微信小程序时运用 echarts 图表
下一篇:修改微信号所带来的影响究竟有哪些
相关文章

 发表评论

暂时没有评论,来抢沙发吧~