zoukankan      html  css  js  c++  java
  • APP微信支付 前端uniapp 后端netcore 实现方法

    APP微信支付 前端uniapp  后端netcore 实现方法

    1、前端uniapp实现方法

    2、前端代码uniapp

      1 <template>
      2     <view class="container">
      3         <view class="uni-padding-wrap">
      4             <view style="background:#FFF; padding:50rpx 0;">
      5                 <view class="uni-h1 uni-center uni-common-mt">
      6                     <text class="rmbLogo">¥</text>
      7                     <input class="price" type="digit" :value="price" maxlength="4" @input="priceChange" />
      8                 </view>
      9             </view>
     10             <view>
     11                 <view v-for="(item,index) in providerList" :key="index" @tap="requestPayment(item,index)">
     12                     {{item.name}}支付
     13                 </view>
     14             </view>
     15         </view>
     16     </view>
     17 </template>
     18 <script>
     19     export default {
     20         data() {
     21             return {
     22                 price: 1,
     23                 providerList: []
     24             }
     25         },
     26         onLoad: function() {
     27             // #ifdef APP-PLUS
     28             uni.getProvider({
     29                 service: "payment",
     30                 success: (e) => {
     31                     console.log("payment success:" + JSON.stringify(e));
     32                     let providerList = [];
     33                     e.provider.map((value) => {
     34                         switch (value) {
     35                             case 'alipay':
     36                                 providerList.push({
     37                                     name: '支付宝',
     38                                     id: value,
     39                                     loading: false
     40                                 });
     41                                 break;
     42                             case 'wxpay':
     43                                 providerList.push({
     44                                     name: '微信',
     45                                     id: value,
     46                                     loading: false
     47                                 });
     48                                 break;
     49                             default:
     50                                 break;
     51                         }
     52                     })
     53                     this.providerList = providerList;
     54                 },
     55                 fail: (e) => {
     56                     console.log("获取支付通道失败:", e);
     57                 }
     58             });
     59             // #endif
     60         },
     61         methods: {
     62             async requestPayment(e, index) {
     63                 this.providerList[index].loading = true;
     64                 let orderInfo = await this.getOrderInfo(e.id);
     65                 console.log("得到订单信息", orderInfo);
     66                 if (orderInfo.statusCode !== 200) {
     67                     console.log("获得订单信息失败", orderInfo);
     68                     uni.showModal({
     69                         content: "获得订单信息失败",
     70                         showCancel: false
     71                     })
     72                     return;
     73                 }
     74                 
     75                 uni.requestPayment({
     76                     provider: e.id,
     77                     orderInfo: orderInfo.data.Data,
     78                     success: (e) => {
     79                         console.log("success", e);
     80                         uni.showToast({
     81                             title: "感谢您的赞助!"
     82                         })
     83                     },
     84                     fail: (e) => {
     85                         console.log("fail", e);
     86                         uni.showModal({
     87                             content: "支付失败,原因为: " + e.errMsg,
     88                             showCancel: false
     89                         })
     90                     },
     91                     complete: () => {
     92                         this.providerList[index].loading = false;
     93                     }
     94                 })
     95             },
     96             getOrderInfo(e) {
     97                 let out_trade_no='订单号';
     98                 let url = '你的服务端apiURL/APP_Pay?type=1&out_trade_no='+out_trade_no+'&total_fee=' + this.price;
     99                 return new Promise((res) => {
    100                     uni.request({
    101                         url: url,
    102                         success: (result) => {
    103                             res(result);
    104                             console.log(JSON.stringify(result));
    105                         },
    106                         fail: (e) => {
    107                             res(e);
    108                             console.log("eee:" + JSON.stringify(e));
    109                         }
    110                     })
    111                 })
    112             },
    113             priceChange(e) {
    114                 console.log(e.detail.value)
    115                 this.price = e.detail.value;
    116             }
    117         }
    118     }
    119 </script>
    120 
    121 <style>
    122     .price {
    123         border-bottom: 1px solid #eee;
    124          200rpx;
    125         height: 80rpx;
    126         padding-bottom: 4rpx;
    127     }
    128 </style>

    3、后端netcore

      1 using Microsoft.AspNetCore.Http;
      2 using Microsoft.AspNetCore.Mvc;
      3 using System;
      4 using System.Collections.Generic;
      5 using System.Security.Cryptography;
      6 using System.Text;
      7 using System.Xml;
      8 
      9 namespace YiSha.Admin.WebApi.Controllers
     10 {
     11     [Route("[controller]/[action]")]
     12     [ApiController]
     13     [AuthorizeFilter]
     14     public class AppPayController : ControllerBase
     15     {
     16         //请求方式:http get
     17         //接口参数说明
     18         //名称    类型 必填    说明
     19         //out_trade_no    string 是    支付订单ID
     20         //total_fee    Double 是    支付金额
     21         //type    int 是    1.安卓,2.IOS
     22 
     23         //返回示例:
     24         ///****失败示例**/
     25         //{
     26         //"Code":1, /*状态码  1:失败 2:成功 */
     27         //"Message":"错误信息",/*消息(一般失败时,返回错误信息)*/
     28         //"Tag":""/*附加信息*/
     29         //}
     30         ///****成功示例**/
     31         //{
     32         //"Code":2, /*状态码  1:失败 2:成功*/
     33         //“Data”:[]
     34         //"Message":"",/*消息(一般失败时,返回错误信息)*/
     35         //"Tag":"附加信息"/* */
     36         //}
     37         //接口返回Data集合参数说明
     38         //名称    类型 说明
     39         //appid string 应用ID
     40         //partnerid String     商户号
     41         //prepayid    String 预支付交易会话ID
     42         //package String    扩展字段
     43         //noncestr    String 随机字符串
     44         //timestamp String    时间戳
     45         //sign    String 签名
     46 
     47         #region 微信APP支付接口
     48         /// <summary>
     49         /// APP_Pay微信APP支付接口
     50         /// </summary>
     51         /// <param name="out_trade_no">支付订单号</param
     52         /// <param name="total_fee">支付金额</param>
     53         /// <param name="type">1.安卓,2.IOS</param>
     54         /// <returns></returns>
     55         [HttpGet]
     56 
     57         public CommonResponse<Wx_pay> APP_Pay(string out_trade_no, Double total_fee, int type)
     58         {
     59             PayMent pm = new PayMent();
     60             HttpContextAccessor context = new HttpContextAccessor();
     61             string ip = context.HttpContext?.Connection.RemoteIpAddress.ToString();
     62             int money = int.Parse((total_fee * 100).ToString());
     63             Wx_pay wp = pm.APP_PayMent("服务费", ip, money, out_trade_no, type);
     64             if (wp.sign == "")
     65             {
     66                 return new CommonResponse<Wx_pay> { Data = null, Message = "系统异常,联系管理员!", Code = 1 };
     67             }
     68             return new CommonResponse<Wx_pay> { Data = wp, Message = String.Empty, Code = 2 };
     69         }
     70         #endregion
     71     }
     72     ///
     73     ///是对返回数据类型
     74     ///
     75     public class CommonResponse<T>
     76     {
     77         /// <summary>
     78         /// 数据
     79         /// </summary>
     80         public T Data { get; set; }
     81         /// <summary>
     82         /// 代码  1:失败,2:成功
     83         /// </summary>
     84         public int Code { get; set; }
     85         /// <summary>
     86         /// 消息
     87         /// </summary>
     88         public string Message { get; set; }
     89         /// <summary>
     90         /// 其他附带信息
     91         /// </summary>
     92         public string Tag { get; set; }
     93     }
     94 
     95     /// <summary>
     96     /// 微信APP支付实体
     97     /// </summary>
     98     public class Wx_pay
     99     {
    100         /// <summary>
    101         /// 应用ID
    102         /// </summary>
    103         public string appid { set; get; } = "";
    104         /// <summary>
    105         /// 商户号
    106         /// </summary>
    107         public string partnerid { set; get; } = "";
    108         /// <summary>
    109         /// 预支付交易会话ID
    110         /// </summary>
    111         public string prepayid { set; get; } = "";
    112         /// <summary>
    113         /// 扩展字段
    114         /// </summary>
    115         public string package { set; get; } = "Sign=WXPay";
    116         /// <summary>
    117         /// 随机字符串
    118         /// </summary>
    119         public string noncestr { set; get; } = "";
    120         /// <summary>
    121         /// 时间戳
    122         /// </summary>
    123         public string timestamp { set; get; } = "";
    124 
    125         /// <summary>
    126         /// 签名
    127         /// </summary>
    128         public string sign { set; get; } = "";
    129     }
    130 
    131     /// <summary>
    132     /// 
    133     /// </summary>
    134     public class PayMent {
    135         #region 微信APP支付
    136         /// <summary>
    137         /// 微信APP支付
    138         /// </summary>
    139         /// <param name="boby">商品描述</param>
    140         /// <param name="mch_id">商户号</param>
    141         /// <param name="spbill_create_ip">终端IP</param>
    142         /// <param name="total_fee">金额</param>
    143         /// <param name="out_trade_no">商户订单号</param>
    144         /// <param name="type">1安卓2苹果</param>
    145         /// <returns></returns>
    146         public Wx_pay APP_PayMent(string boby, string spbill_create_ip, int total_fee, string out_trade_no, int type)
    147         {
    148             UnifiedOrder order = new UnifiedOrder();
    149             if (type == 1)
    150             {
    151                 order.appid = APP_Aconfig.appid;
    152                 order.mch_id = APP_Aconfig.partnerid;
    153             }
    154             else
    155             {
    156                 order.appid = APP_Iconfig.appid;
    157                 order.mch_id = APP_Iconfig.partnerid;
    158             }
    159             order.attach = "APP名称-支付内容说明";
    160             order.body = boby;
    161             order.device_info = "WEB";
    162             order.nonce_str = TenpayUtil.getNoncestr();
    163             order.notify_url = APP_Aconfig.url;
    164             order.out_trade_no = out_trade_no;
    165             order.trade_type = "APP";
    166             order.spbill_create_ip = spbill_create_ip;
    167             order.total_fee = total_fee;
    168             TenpayUtil tenpay = new TenpayUtil();
    169             string paySignKey = string.Empty;
    170             if (type == 1)
    171             {
    172                 paySignKey = APP_Aconfig.paysignkey;
    173             }
    174             else
    175             {
    176                 paySignKey = APP_Iconfig.paysignkey;
    177             }
    178             string prepay_id = tenpay.getPrepay_id(order, paySignKey);
    179             string timeStamp = TenpayUtil.getTimestamp();
    180             string nonceStr = TenpayUtil.getNoncestr();
    181             SortedDictionary<string, object> sParams = new SortedDictionary<string, object>();
    182             sParams.Add("appid", order.appid);
    183             sParams.Add("partnerid", order.mch_id);
    184             sParams.Add("prepayid", prepay_id);
    185             sParams.Add("noncestr", nonceStr);
    186             sParams.Add("timestamp", timeStamp);
    187             sParams.Add("package", "Sign=WXPay");
    188             string paySign = tenpay.getsign(sParams, paySignKey);
    189             Wx_pay wp = new Wx_pay();
    190             wp.appid = order.appid;
    191             wp.partnerid = order.mch_id;
    192             wp.noncestr = nonceStr;
    193             wp.prepayid = prepay_id;
    194             wp.sign = paySign;
    195             wp.timestamp = timeStamp;
    196             return wp;
    197         }
    198         #endregion
    199     }
    200     /// <summary>
    201     /// APP安卓支付配置
    202     /// </summary>
    203     public class APP_Aconfig
    204     {
    205         public const string appid = "";//APPID
    206         public const string partnerid = "";//商户号
    207         public const string paysignkey = ""; //证书密匙商户平台APIkey
    208         public const string url = "";//回调ur
    209     }
    210 
    211     /// <summary>
    212     /// APPios 支付配置
    213     /// </summary>
    214     public class APP_Iconfig
    215     {
    216         public const string appid = "";//APPID
    217         public const string partnerid = "";//商户号
    218         public const string paysignkey = "";//证书密匙
    219         public const string url = "";//回调url
    220     }
    221     //-------TenpayUtil类
    222     /// <summary>
    223     /// 
    224     /// </summary>
    225     public class TenpayUtil
    226     {
    227         /// <summary>
    228         /// 统一支付接口
    229         /// </summary>
    230         const string UnifiedPayUrl = "https://api.mch.weixin.qq.com/pay/unifiedorder";
    231         /// <summary>
    232         /// 随机串
    233         /// </summary>
    234         public static string getNoncestr()
    235         {
    236             Random random = new Random();
    237             return MD5Util.GetMD5(random.Next(1000).ToString(), "GBK").ToLower().Replace("s", "S");
    238         }
    239 
    240         /// <summary>
    241         /// 时间截,自1970年以来的秒数
    242         /// </summary>
    243 
    244         public static string getTimestamp()
    245         {
    246             TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0);
    247             return Convert.ToInt64(ts.TotalSeconds).ToString();
    248         }
    249 
    250         /// <summary>
    251         /// 获取微信签名
    252         /// </summary>
    253         /// <param name="sParams"></param>
    254         /// <returns></returns>
    255 
    256         public string getsign(SortedDictionary<string, object> sParams, string key)
    257         {
    258             int i = 0;
    259             string sign = string.Empty;
    260             StringBuilder sb = new StringBuilder();
    261             foreach (KeyValuePair<string, object> temp in sParams)
    262             {
    263                 if (temp.Value.ToString() == "" || temp.Value == null || temp.Key.ToLower() == "sign")
    264                 {
    265                     continue;
    266                 }
    267                 i++;
    268                 sb.Append(temp.Key.Trim() + "=" + temp.Value.ToString() + "&");
    269             }
    270             sb.Append("key=" + key.Trim() + "");
    271             string signkey = sb.ToString();
    272             sign = MD5Util.GetMD5(signkey, "utf-8");
    273             return sign;
    274         }
    275 
    276         /// <summary>
    277         /// post数据到指定接口并返回数据
    278         /// </summary>
    279 
    280         public string PostXmlToUrl(string url, string postData)
    281         {
    282             string returnmsg = "";
    283             using (System.Net.WebClient wc = new System.Net.WebClient())
    284             {
    285                 returnmsg = wc.UploadString(url, "POST", postData);
    286             }
    287             return returnmsg;
    288         }
    289 
    290         /// <summary>
    291         /// 获取prepay_id
    292         /// </summary>
    293 
    294         public string getPrepay_id(UnifiedOrder order, string key)
    295         {
    296             string prepay_id = "";
    297             string post_data = getUnifiedOrderXml(order, key);
    298             string request_data = PostXmlToUrl(UnifiedPayUrl, post_data);
    299             SortedDictionary<string, object> requestXML = GetInfoFromXml(request_data);
    300             foreach (KeyValuePair<string, object> k in requestXML)
    301             {
    302                 if (k.Key == "prepay_id")
    303                 {
    304                     prepay_id = k.Value.ToString();
    305                     break;
    306                 }
    307             }
    308             return prepay_id;
    309         }
    310 
    311         /// <summary>
    312         /// 把XML数据转换为"SortedDictionary<string, string>"集合
    313         /// </summary>
    314         /// <param name="strxml"></param>
    315         /// <returns>
    316         /// 
    317         /// </returns>
    318         protected SortedDictionary<string, object> GetInfoFromXml(string xmlstring)
    319         {
    320             SortedDictionary<string, object> sParams = new SortedDictionary<string, object>();
    321             try
    322             {
    323                 XmlDocument doc = new XmlDocument();
    324                 doc.LoadXml(xmlstring);
    325                 XmlElement root = doc.DocumentElement;
    326                 int len = root.ChildNodes.Count;
    327                 for (int i = 0; i < len; i++)
    328                 {
    329                     string name = root.ChildNodes[i].Name;
    330                     if (!sParams.ContainsKey(name))
    331                     {
    332                         sParams.Add(name.Trim(), root.ChildNodes[i].InnerText.Trim());
    333                     }
    334                 }
    335             }
    336             catch { }
    337             return sParams;
    338         }
    339 
    340         /// <summary>
    341         /// 微信统一下单接口xml参数整理
    342         /// </summary>
    343         /// <param name="order">微信支付参数实例</param>
    344         /// <param name="key">密钥</param>
    345         /// <returns></returns>
    346 
    347         protected string getUnifiedOrderXml(UnifiedOrder order, string key)
    348         {
    349             string return_string = string.Empty;
    350             SortedDictionary<string, object> sParams = new SortedDictionary<string, object>();
    351             sParams.Add("appid", order.appid);
    352             sParams.Add("attach", order.attach);
    353             sParams.Add("body", order.body);
    354             sParams.Add("device_info", order.device_info);
    355             sParams.Add("mch_id", order.mch_id);
    356             sParams.Add("nonce_str", order.nonce_str);
    357             sParams.Add("notify_url", order.notify_url);
    358             sParams.Add("openid", order.openid);
    359             sParams.Add("out_trade_no", order.out_trade_no);
    360             sParams.Add("spbill_create_ip", order.spbill_create_ip);
    361             sParams.Add("total_fee", order.total_fee);
    362             sParams.Add("trade_type", order.trade_type);
    363             order.sign = getsign(sParams, key);
    364             sParams.Add("sign", order.sign);
    365             //拼接成XML请求数据
    366             StringBuilder sbPay = new StringBuilder();
    367             foreach (KeyValuePair<string, object> k in sParams)
    368             {
    369                 if (k.Key == "attach" || k.Key == "body" || k.Key == "sign")
    370                 {
    371                     sbPay.Append("<" + k.Key + "><![CDATA[" + k.Value + "]]></" + k.Key + ">");
    372                 }
    373                 else
    374                 {
    375                     sbPay.Append("<" + k.Key + ">" + k.Value + "</" + k.Key + ">");
    376                 }
    377             }
    378             return_string = string.Format("<xml>{0}</xml>", sbPay.ToString());
    379             return return_string;
    380         }
    381     }
    382 
    383     //---微信统一接口请求实体对象
    384     /// <summary>
    385     /// 微信统一接口请求实体对象
    386     /// </summary>
    387     [Serializable]
    388     public class UnifiedOrder
    389     {
    390         /// <summary>
    391         /// 公众号ID(微信分配的公众账号 ID)
    392         /// </summary>
    393         public string appid = "";
    394         /// <summary>
    395         /// 商户号(微信支付分配的商户号)
    396         /// </summary>
    397         public string mch_id = "";
    398         /// <summary>
    399         /// 微信支付分配的终端设备号
    400         /// </summary>
    401         public string device_info = "";
    402         /// <summary>
    403         /// 随机字符串,不长于 32 位
    404         /// </summary>
    405         public string nonce_str = "";
    406         /// <summary>
    407         /// 签名
    408         /// </summary>
    409         public string sign = "";
    410         /// <summary>
    411         /// 商品描述
    412         /// </summary>
    413         public string body = "";
    414         /// <summary>
    415         /// 附加数据,原样返回
    416         /// </summary>
    417         public string attach = "";
    418         /// <summary>
    419         /// 商户系统内部的订单号,32个字符内、可包含字母,确保在商户系统唯一,详细说明
    420         /// </summary>
    421         public string out_trade_no = "";
    422         /// <summary>
    423         /// 订单总金额,单位为分,不能带小数点
    424         /// </summary>
    425         public int total_fee = 0;
    426         /// <summary>
    427         /// 终端IP
    428         /// </summary>
    429         public string spbill_create_ip = "";
    430         /// <summary>
    431         /// 订 单 生 成 时 间 , 格 式 为yyyyMMddHHmmss,如 2009 年12 月 25 日 9 点 10 分 10 秒表示为 20091225091010。时区为 GMT+8 beijing。该时间取自商户服务器
    432         /// </summary>
    433         public string time_start = "";
    434         /// <summary>
    435         /// 交易结束时间
    436         /// </summary>
    437         public string time_expire = "";
    438         /// <summary>
    439         /// 商品标记 商品标记,该字段不能随便填,不使用请填空,使用说明详见第 5 节
    440         /// </summary>
    441         public string goods_tag = "";
    442         /// <summary>
    443         /// 接收微信支付成功通知
    444         /// </summary>
    445         public string notify_url = "";
    446         /// <summary>
    447         /// JSAPI、NATIVE、APP
    448         /// </summary>
    449         public string trade_type = "";
    450         /// <summary>
    451         /// 用户标识 trade_type 为 JSAPI时,此参数必传
    452         /// </summary>
    453         public string openid = "";
    454         /// <summary>
    455         /// 只在 trade_type 为 NATIVE时需要填写。
    456         /// </summary>
    457         public string product_id = "";
    458 
    459     }
    460     /// <summary>
    461     /// 
    462     /// </summary>
    463     public class MD5Util
    464     {
    465         /// <summary>
    466         /// 
    467         /// </summary>
    468         public MD5Util()
    469         {
    470             //
    471             // TODO: 在此处添加构造函数逻辑
    472             //
    473         }
    474         /// <summary>
    475         /// /** 获取大写的MD5签名结果 */
    476         /// </summary>
    477         /// <param name="encypStr">数据</param>
    478         /// <param name="charset">编码格式</param>
    479         /// <returns></returns>
    480 
    481 
    482         public static string GetMD5(string encypStr, string charset)
    483         {
    484             string retStr;
    485             MD5CryptoServiceProvider m5 = new MD5CryptoServiceProvider();
    486 
    487             //创建md5对象
    488             byte[] inputBye;
    489             byte[] outputBye;
    490 
    491             //使用GB2312编码方式把字符串转化为字节数组.
    492             try
    493             {
    494                 inputBye = Encoding.GetEncoding(charset).GetBytes(encypStr);
    495             }
    496             catch (Exception ex)
    497             {
    498                 inputBye = Encoding.GetEncoding("GB2312").GetBytes(encypStr);
    499             }
    500             outputBye = m5.ComputeHash(inputBye);
    501             retStr = System.BitConverter.ToString(outputBye);
    502             retStr = retStr.Replace("-", "").ToUpper();
    503             return retStr;
    504         }
    505         /// <summary>
    506         /// SHA1加密
    507         /// </summary>
    508         /// <param name="str"></param>
    509         /// <returns></returns>
    510         //public static string sha1(string str)
    511         //{
    512         //    return System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(str, "sha1").ToLower();
    513         //}
    514         // 转JSon对象
    515 
    516         /// <summary>
    517         /// json
    518         /// </summary>
    519         /// <returns></returns>
    520 
    521         public static String toJson(string appId, string timeStamp, string nonceStr, string packageA, string signType, string paySign)
    522         {
    523             String json = "{";
    524             json += ""appId":" + """ + appId + "",";
    525             json += ""timeStamp":" + """ + timeStamp + "",";
    526             json += ""nonceStr":" + """ + nonceStr + "",";
    527             json += ""package":" + """ + packageA + "",";
    528             json += ""signType":" + """ + signType + "",";
    529             json += ""paySign":" + """ + paySign + """;
    530             json += "}";
    531             return json;
    532         }
    533 
    534         /// <summary>
    535         /// string转utf-8
    536         /// </summary>
    537         /// <param name="unicodeString"></param>
    538         /// <returns></returns>
    539         public static string get_uft8(string unicodeString)
    540         {
    541             UTF8Encoding utf8 = new UTF8Encoding();
    542             Byte[] encodedBytes = utf8.GetBytes(unicodeString);
    543             String decodedString = utf8.GetString(encodedBytes);
    544             return decodedString;
    545         }
    546     }
    547 
    548 }

    注:本代码只做了微信支付,亲测可用

  • 相关阅读:
    Redis主从同步分析(转)
    Jedis使用总结【pipeline】【分布式的id生成器】【分布式锁【watch】【multi】】【redis分布式】(转)
    PHP之PDO_MYSQL扩展安装步骤(转)
    MongoDB 那些坑(转)
    CF 222 (DIV 1)
    TC SRM601
    TC SRM600 DIV2
    Github入门教程
    2013长春区域赛总结
    退役了~~~~~~~~~~~~
  • 原文地址:https://www.cnblogs.com/wishit/p/14020113.html
Copyright © 2011-2022 走看看