using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using Edu.Common.WeChatPayAPIv3.Model.GenerateOrder;
using Edu.Common.WeChatPayAPIv3.Model.QueryOrder;
using Edu.Common.WeChatPayAPIv3.Model.QueryRefunds;
using Edu.Common.WeChatPayAPIv3.Model.Refunds;
namespace Edu.Common.WeChatPayAPIv3
{
public class WxPayHelper
{
///
/// 直连商户申请的公众号或移动应用appid。
///
private string _appid { set; get; }
///
/// 直连商户的商户号,由微信支付生成并下发。
///
private string _mchid { set; get; }
///
/// 证书序列号,查看证书序列号:https://wechatpay-api.gitbook.io/wechatpay-api-v3/chang-jian-wen-ti/zheng-shu-xiang-guan#ru-he-cha-kan-zheng-shu-xu-lie-hao
///
private string _serialNo;
///
/// 私钥不包括私钥文件起始的-----BEGIN PRIVATE KEY----- 亦不包括结尾的-----END PRIVATE KEY-----
///
private string _privateKey;
///
/// 构造函数
///
/// 直连商户申请的公众号或移动应用appid
/// 直连商户的商户号,由微信支付生成并下发
/// 证书序列号,查看证书序列号:https://wechatpay-api.gitbook.io/wechatpay-api-v3/chang-jian-wen-ti/zheng-shu-xiang-guan#ru-he-cha-kan-zheng-shu-xu-lie-hao
/// 私钥不包括私钥文件起始的-----BEGIN PRIVATE KEY----- 亦不包括结尾的-----END PRIVATE KEY-----
public WxPayHelper(string appid, string mchid, string serialNo, string privateKey)
{
_appid = appid;
_mchid = mchid;
_serialNo = serialNo;
_privateKey = privateKey;
}
///
/// 统一下单接口,只对接了必填的字段
///
/// 商品描述
/// 订单总金额,单位为分
/// 商户系统内部订单号,只能是数字、大小写字母_-*且在同一个商户号下唯一
/// 通知URL必须为直接可访问的URL,不允许携带查询串。格式:URL
/// 附加数据,在查询API和支付通知中原样返回,可作为自定义参数使用
/// 货币类型,CNY:人民币,境内商户号仅支持人民币
///
public async Task UnionGenerateOrder(string description, int price, string out_trade_no, string notify_url, string attach = "", string currency = "CNY")
{
var url = "https://api.mch.weixin.qq.com/v3/pay/transactions/native";
var req = new GenerateOrderModelForWxPay
{
appid = this._appid,
mchid = this._mchid,
description = description,
amount = new WxPayAmountModel
{
total = price,
currency = currency
},
out_trade_no = out_trade_no,
attach = attach,
notify_url = notify_url
};
var client = new HttpClient(new WxPayRequestHandler(_mchid, _serialNo, _privateKey));
// var bodyJson = new StringContent(req.ToJson(), Encoding.UTF8, "application/json");
var bodyJson = new StringContent(Common.Plugin.JsonHelper.Serialize(req), Encoding.UTF8, "application/json");
var resp = await client.PostAsync(url, bodyJson);
// 注意!!! 这个resp只是http的结果,需要把接口具体返回的值读取出来,如果接口报错的话,这地方可以看到具体的错误信息,我就是在这里入坑的。
var respStr = await resp.Content.ReadAsStringAsync();
// 如果下单成功,就解析返回的结果,把prepay_id解析出来
// var viewModel = respStr.ToObject();
Plugin.LogHelper.WriteInfo(respStr);
var viewModel = Common.Plugin.JsonHelper.DeserializeObject(respStr);
return viewModel;
}
///
/// 查询订单
///
/// 商户自己的订单号,不是微信生成的订单号
public async Task QueryOrder(string orderNumber)
{
var url = $"https://api.mch.weixin.qq.com/v3/pay/transactions/out-trade-no/{orderNumber}?mchid={ this._mchid}";
var client = new HttpClient(new WxPayRequestHandler(_mchid, _serialNo, _privateKey));
var resp = await client.GetAsync(url);
var respStr = await resp.Content.ReadAsStringAsync();
Plugin.LogHelper.WriteInfo("查询订单的支付结果信息:"+respStr);
var payModel = Common.Plugin.JsonHelper.DeserializeObject(respStr);// respStr.ToObject();
return payModel;
}
/////
///// 关闭订单
/////
///// 商户自己的订单号,不是微信生成的订单号
//public async Task ClostOrder(string orderNumber)
//{
// var url = $"https://api.mch.weixin.qq.com/v3/pay/transactions/out-trade-no/{orderNumber}/close";
// var client = new HttpClient(new WxPayRequestHandler(_mchid, _serialNo, _privateKey));
// var bodyJson = new StringContent(new { mchid = this._mchid }.ToJson(), Encoding.UTF8, "application/json");
// var resp = await client.PostAsync(url, bodyJson);
// var respStr = await resp.Content.ReadAsStringAsync();
// var closeModel = new ClostOrderRespModel();
// if (!string.IsNullOrEmpty(respStr))
// closeModel = respStr.ToObject();
// closeModel.StatusCode = resp.StatusCode.ToString();
// return closeModel;
//}
///
/// 微信支付申请退款接口
///
/// 商户系统内部订单号,只能是数字、大小写字母_-*且在同一个商户号下唯一;原支付交易对应的商户订单号。
/// 商户系统内部的退款单号,商户系统内部唯一,只能是数字、大小写字母_-|*@ ,同一退款单号多次请求只退一笔。
/// 若商户传入,会在下发给用户的退款消息中体现退款原因。
/// 退款金额,币种的最小单位,只能为整数,不能超过原订单支付金额。
/// 原支付交易的订单总金额,币种的最小单位,只能为整数。
/// 异步接收微信支付退款结果通知的回调地址,通知url必须为外网可访问的url,不能携带参数。 如果参数中传了notify_url,则商户平台上配置的回调地址将不会生效,优先回调当前传的这个地址。示例值:https://weixin.qq.com ,必须是https的网址
/// 符合ISO 4217标准的三位字母代码,目前只支持人民币:CNY。
///
public async Task Refunds(string out_trade_no, string out_refund_no, string reason, int refund, int total, string notify_url = "", string currency = "CNY")
{
var req = new RefundsRequestModel
{
out_refund_no = out_refund_no,
out_trade_no = out_trade_no,
reason = reason,
notify_url = notify_url,
amount = new RefundsAmountModel
{
refund = refund,
total = total,
currency = currency
}
};
var url = $"https://api.mch.weixin.qq.com/v3/refund/domestic/refunds";
var client = new HttpClient(new WxPayRequestHandler(_mchid, _serialNo, _privateKey));
var bodyJson = new StringContent(Common.Plugin.JsonHelper.Serialize(req), Encoding.UTF8, "application/json");
var resp = await client.PostAsync(url, bodyJson);
var respStr = await resp.Content.ReadAsStringAsync();
var payModel = Common.Plugin.JsonHelper.DeserializeObject(respStr);// respStr.ToObject();
return payModel;
}
///
/// 查询退款结果
///
/// 商户系统内部的退款单号,商户系统内部唯一,只能是数字、大小写字母_-|*@ ,同一退款单号多次请求只退一笔。
public async Task QueryRefundsOrder(string out_refund_no)
{
var url = $"https://api.mch.weixin.qq.com/v3/refund/domestic/refunds/{out_refund_no}";
var client = new HttpClient(new WxPayRequestHandler(_mchid, _serialNo, _privateKey));
var resp = await client.GetAsync(url);
var respStr = await resp.Content.ReadAsStringAsync();
Plugin.LogHelper.WriteInfo("查询订单的退款结果信息:" + respStr);
var payModel = Common.Plugin.JsonHelper.DeserializeObject(respStr); //respStr.ToObject();
return payModel;
}
}
}