.NET Core 实现微信小程序支付功能(统一下单)

.NET Core 实现微信小程序支付功能(统一下单)攻略

微信小程序支付功能是一种常见的电商需求,本攻略将介绍如何使用.NET Core实现微信小程序支付功能的统一下单流程。

基本流程

微信小程序支付主要包含以下基本流程:

  1. 用户在小程序中选择商品并发起支付请求;
  2. 小程序调用开发者服务器,向后端发送订单信息;
  3. 开发者服务器向微信支付服务器发起统一下单请求;
  4. 微信支付服务器响应统一下单请求,返回预支付交易会话标识prepay_id;
  5. 开发者服务器向小程序返回prepay_id,小程序根据此参数调用微信支付SDK拉起支付页面;
  6. 用户完成支付,小程序向微信支付服务器发起支付结果查询请求,查询交易是否成功。

综上所述,微信小程序支付功能涉及到小程序、开发者服务器、微信支付服务器三方的协同配合,开发流程相对较为复杂。

下面我们将具体介绍.NET Core实现微信小程序支付功能的基本流程及代码实现。

统一下单流程

1. 安装微信支付SDK

我们需要通过NuGet安装微信支付SDK,安装命令如下:

dotnet add package Senparc.Weixin.WxOpen.dll --version 3.4.1

2. 配置微信支付相关参数

微信支付涉及到公钥、私钥、商户号、AppID等参数的配置,我们需要在appsettings.json文件中添加如下配置:

{
  "WeixinPayConfig": {
    "AppId": "your_app_id",
    "MchId": "your_mch_id",
    "Key": "your_key",
    "AppSecret": "your_app_secret",
    "CertPath": "your_cert_path",
    "CertPassword": "your_cert_password"
  }
}

3. 实现统一下单接口

我们需要在开发者服务器上实现统一下单接口,代码如下:

[HttpPost("/api/pay")]
public async Task<WeixinPayResult> PayAsync([FromBody]WeixinPayRequest request)
{
    var result = await _weixinPayService.UnifiedOrderAsync(request);
    return result;
}

其中,WeixinPayRequest是前端请求支付时发送给后端的参数类,包含商品名称、价格、商户订单号等信息;WeixinPayResult则是后端返回给前端的结果类,包含prepay_id、app_id、nonce_str等信息。

4. 调用微信支付SDK发起预支付交易请求

我们需要在后端实现调用微信支付SDK发起预支付交易请求的逻辑,代码如下:

public async Task<WeixinPayResult> UnifiedOrderAsync(WeixinPayRequest request)
{
    var payment = new WxPayData();
    payment.SetValue("body", request.Body);
    payment.SetValue("out_trade_no", request.OutTradeNo);
    payment.SetValue("total_fee", request.TotalFee);
    payment.SetValue("trade_type", "JSAPI");
    payment.SetValue("openid", request.OpenId);

    var result = await WxPayApi.UnifiedOrderAsync(payment);

    var nonceStr = Guid.NewGuid().ToString("N").Substring(0, 16);
    var timeStamp = WxPayApi.GenerateTimeStamp();

    var paySign = result.MakeSign();
    var jsApiParam = new WxPayData();
    jsApiParam.SetValue("appId", _weixinPayConfig.AppId);
    jsApiParam.SetValue("timeStamp", timeStamp);
    jsApiParam.SetValue("nonceStr", nonceStr);
    jsApiParam.SetValue("package", $"prepay_id={result.GetValue("prepay_id")}");
    jsApiParam.SetValue("signType", "MD5");
    jsApiParam.SetValue("paySign", paySign);

    return new WeixinPayResult
    {
        PrepayId = result.GetValue("prepay_id").ToString(),
        AppId = _weixinPayConfig.AppId,
        NonceStr = nonceStr,
        TimeStamp = timeStamp,
        SignType = "MD5",
        Package = $"prepay_id={result.GetValue("prepay_id")}",
        PaySign = paySign
    };
}

其中,WeixinPayRequest和WeixinPayResult我们已经在之前定义过了;WxPayData和WxPayApi是微信支付SDK中的类和方法,用于封装支付请求和发送请求。

5. 拉起支付页面

我们可以在小程序中发送支付请求并处理支付结果,代码如下:

wx.request({
  url: 'https://your_api_host/api/pay',
  method: 'POST',
  data: {
    body: "测试商品",
    outTradeNo: "test123",
    totalFee: 1,
    openId: "your_open_id"
  },
  success: function (res) {
    wx.requestPayment({
      appId: res.data.appId,
      timeStamp: res.data.timeStamp,
      nonceStr: res.data.nonceStr,
      package: res.data.package,
      signType: res.data.signType,
      paySign: res.data.paySign,
      success: function (result) {
        console.log(result);
      },
      fail: function (fail) {
        console.log(fail);
      }
    });
  }
});

其中,我们在小程序中向开发者服务器发送支付请求,成功后将返回的prepay_id等参数传给SDK,拉起微信支付窗口供用户进行支付操作。

6. 查询支付结果

我们也可以在后端实现查询支付结果的逻辑,代码如下:

public async Task<WxPayData> OrderQueryAsync(string transactionId = "", string outTradeNo = "")
{
    var inputObj = new WxPayData();
    if (!string.IsNullOrEmpty(transactionId))
    {
        inputObj.SetValue("transaction_id", transactionId);
    }
    else
    {
        inputObj.SetValue("out_trade_no", outTradeNo);
    }

    var result = await WxPayApi.OrderQueryAsync(inputObj);

    return result;
}

其中,transactionId和outTradeNo分别为微信支付服务器返回的transaction_id和商户订单号,用于查询支付结果。

示例说明

我们以CSharpWinForm开源项目作为示例进行支付功能的演示。

示例1:添加支付按钮

我们在商品详情页面添加支付按钮,一旦用户点击该按钮,将发起向开发者服务器的支付请求:

private void btnPay_Click(object sender, EventArgs e)
{
    var request = new RestRequest("api/pay", Method.POST);
    request.AddJsonBody(new WeixinPayRequest
    {
        Body = _goods.Title,
        OutTradeNo = Guid.NewGuid().ToString(),
        TotalFee = Convert.ToInt32(_goods.Price * 100),
        OpenId = _openId
    });

    var response = _client.Execute<WeixinPayResult>(request);
    var result = response.Data;

    if (result != null)
    {
        var jsApiParam = new JavaScriptSerializer().Serialize(new
        {
            appId = result.AppId,
            timeStamp = result.TimeStamp,
            nonceStr = result.NonceStr,
            package = result.Package,
            signType = result.SignType,
            paySign = result.PaySign
        });

        webBrowser1.Url = new Uri("https://mp.weixin.qq.com/mp/wapapp/wapapp_pay_verify.php?platform=html5&" +
            "jsapi=" + jsApiParam + "&prepay_id=" + result.PrepayId + "&redirect_url=http%3a%2f%2fwww.weixin.qq.com" +
            "&wxpay=true&appid=" + result.AppId + "&total_fee=" + result.TotalFee);
    }
    else
    {
        MessageBox.Show("支付失败");
    }
}

示例2:查询支付结果

我们在订单详情页面添加查询支付结果按钮,一旦用户点击该按钮,将查询最新的支付结果并展示给用户:

private async void btnQuery_Click(object sender, EventArgs e)
{
    var request = new RestRequest("api/pay/query", Method.POST);
    request.AddJsonBody(new { transactionId = _order.TransactionId });
    var response = await _client.ExecuteTaskAsync<WxPayData>(request);
    var result = response.Data;

    if (result != null && result.GetValue("return_code").ToString() == "SUCCESS" &&
        result.GetValue("result_code").ToString() == "SUCCESS" && result.GetValue("trade_state").ToString() == "SUCCESS")
    {
        MessageBox.Show("支付成功");
    }
    else
    {
        MessageBox.Show("支付失败");
    }
}

总结

通过本攻略的介绍,相信大家已经掌握了.NET Core实现微信小程序支付功能的基本流程及代码实现,希望对大家有所帮助。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:.NET Core 实现微信小程序支付功能(统一下单) - Python技术站

(0)
上一篇 2023年5月30日
下一篇 2023年5月30日

相关文章

  • PHP输出缓存ob系列函数详解

    PHP输出缓存ob系列函数详解 什么是输出缓存? 在开发 Web 应用程序时,我们常常遇到生成大量 HTML 或其他格式内容的情况。这些输出内容会立即发送到请求客户端的浏览器,给服务器带来了很大的压力。输出缓存就是为了优化网络传输,将输出内容先缓存下来,等到有足够大小或者执行完毕后,才一次性输出到客户端。 ob系列函数 PHP 提供了一系列的输出控制函数,也…

    PHP 2023年5月26日
    00
  • 微信etc怎么激活?微信etc使用教程详解

    微信etc怎么激活? 要使用微信等线上支付方式支付ETC费用,需要先完成ETC账户的激活过程。具体步骤如下: 打开 “全国客户服务热线” 所在的省客服电话,完成ETC账户实名认证。 获得ETC账户名、密码和交易密码后,拨打客服电话进行账户激活。 微信etc使用教程详解 完成ETC账户激活后,就可以使用微信等线上支付方式进行ETC费用缴纳了。具体步骤如下: 打…

    PHP 2023年5月23日
    00
  • php FLEA中二叉树数组的遍历输出

    那我就给您详细讲解如何在 PHP FLEA 中进行二叉树数组的遍历输出。 前言 二叉树是常见的一种数据结构,PHP FLEA 框架提供了一种便捷的方式实现二叉树,它可以通过数组的形式组织二叉树结构,而且还提供了遍历整个二叉树的方法。 数组结构 在 FLEA 中,使用一维数组来组织二叉树的结构,每个数组元素都代表一个二叉树节点,其包含以下几个部分: uri: …

    PHP 2023年5月26日
    00
  • golang实现PHP数组特性的方法

    让我来详细讲解一下“golang实现PHP数组特性的方法”的完整攻略。 什么是PHP数组特性 在PHP中,数组是一种非常常见的数据类型。PHP数组具有以下特点: 可以使用整数或字符串作为数组索引 索引是从0开始 可以动态添加、删除和修改元素 可以使用foreach语句遍历数组 如何在golang中实现PHP数组特性 要在golang中实现PHP数组特性,我们…

    PHP 2023年5月26日
    00
  • 详解PHP的7个预定义接口

    PHP的预定义接口是默认情况下在PHP中提供的一系列接口,它们都有着特定的功能和作用,可以方便地让开发者和程序员在其项目中使用和应用。通常,如果有一个实现相应接口的类,那么该类就可以在使用相应接口的任何位置使用,同时也可以享有PHP所有的内置特性和功能。接下来,我将详细讲解PHP的7个预定义接口,并提供至少两个示例说明。 1. Countable Count…

    PHP 2023年5月27日
    00
  • 一个PHP分页类的代码

    下面是一个PHP分页类的完整攻略: 什么是分页? 分页,是指将一段较长的数据分割成若干个小的数据块,以方便用户浏览,也叫翻页。常见于各种网站的查询结果、产品列表、文章列表等。 为什么需要分页? 不分页可能会导致页面加载速度过慢,用户体验不佳;同时,对于长篇文章、产品列表等较为冗长的信息,通过分页能够更方便地进行相关信息之间的筛选和比较。 PHP分页类示例说明…

    PHP 2023年5月23日
    00
  • PHP实现链式操作的原理详解

    《PHP实现链式操作的原理详解》是一篇介绍PHP语言实现链式操作的文章。链式操作是一种通过在每个方法调用后返回对象本身,从而可以连续调用多个方法的技术。在这篇文章中,我们将介绍链式操作的原理和实现方法。 原理 实现链式操作的原理非常简单:在每个方法中返回对象本身,这样我们就可以连续调用多个方法。 具体来说,我们可以在方法中使用 return $this 来返…

    PHP 2023年5月27日
    00
  • PHP 事务处理数据实现代码

    当我们需要对数据库中的数据进行修改时,通常是需要保证数据的完整性和一致性的,而实现这种要求最常见的方法就是事务处理。在 PHP 中,我们可以使用 mysqli 或 PDO 等数据库扩展来实现事务处理。下面就是 PHP 事务处理数据实现代码的完整攻略: 1. 确定事务处理的数据操作 在进行事务处理之前,需要明确需要执行的数据操作的范围,这包括数据的修改、插入和…

    PHP 2023年5月24日
    00
合作推广
合作推广
分享本页
返回顶部