zhaojs
2023-10-20 539dd16c7ee4da6c4b9d4f953b91f1360bb4a7b4
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
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
using CommonUtil;
using CommonUtil.Web;
using Essensoft.Paylink.WeChatPay;
using Essensoft.Paylink.WeChatPay.V3;
using Essensoft.Paylink.WeChatPay.V3.Domain;
using Essensoft.Paylink.WeChatPay.V3.Notify;
using Essensoft.Paylink.WeChatPay.V3.Request;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using Operater.DAL;
using Operater.DbModel;
using Operater.DTO.Sms;
using Operater.Service;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
 
namespace Api.Operater.Controllers.sms
{
    [Route(TopConstants.SMSAPI_ROUTE)]
    [Route(TopConstants.API_ROUTE, Order = 2)]
    public class WxBackController : BaseController
    {
 
        public static string AppId = "wx7a9a40880081340d";
        public static string Secret = "0570a64c9b7622a66d647689e55aab4d";
        public static string MchId = "1652582679";
        public static string APIv3Key = "42DjmxsL34sHwqiereE23KnS62Slk82W";
        public static string Certificate = "D://勿删//apiclient_cert.p12";
        private readonly IWeChatPayClient _client;
        private readonly IWeChatPayNotifyClient _notifyClient;
        public WxBackController(IWeChatPayClient client, IWeChatPayNotifyClient notifyclient)
        {
            _client = client;
            _notifyClient = notifyclient;
        }
        /// <summary>
        /// 获取微信openid
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [HttpPost]
        public IActionResult GetOpenId([FromBody] GetOpenIdRequest request)
        {
 
            //return Success("ocUrg6nVVPhn-m6yNPg7igYnB64g");
            LogUtil.Info($"授权用code:{request.Code}", "wxLog");
            string getUrl = $"https://api.weixin.qq.com/sns/oauth2/access_token?appid={AppId}&secret={Secret}&code={request.Code}&grant_type=authorization_code";
            string resStr = new WebUtil().DoGet(getUrl, null);
            LogUtil.Info($"[获取openid]返回:{resStr}", "接口请求日志");
            GzhGetOauth2TokenResponse response = JSONUtil.JsonToObject<GzhGetOauth2TokenResponse>(resStr);
            return Success(response.openid);
        }
        /// <summary>
        /// 获取支付信息
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public async Task<IActionResult> GetCreatePayInfo([FromBody] GetCreatePayInfoRequest request)
        {
            //获取充值包信息
            var packageInfo = new SmsPackageDAL().GetById(request.PackageId);
            if (packageInfo.IsNull())
            {
                return Error("充值包不存在!");
            }
            int totalAmount = decimal.ToInt32((decimal)packageInfo.Rechargeamount * 100);
 
            long TradeId = TopUtil.GetId();
            WxpayTrade wxpayTrade = new WxpayTrade()
            {
                Id = TradeId,
                Openid = request.OpenId,
                Amount = totalAmount,
                CreateTime = DateTime.Now,
                HasBack = 0,
                SmsCount = (int)packageInfo.Rechargecount
            };
 
            var model = new WeChatPayTransactionsJsApiBodyModel
            {
                AppId = AppId,
                MchId = MchId,
                Amount = new Amount { Total = totalAmount, Currency = "CNY" },
                Description = $"短信充值{packageInfo.Rechargecount}条短信-共{packageInfo.Rechargeamount}元",
                NotifyUrl = "https://smsapi.ushopvip.com/smsapi/WxBack/WxPayBack",
                OutTradeNo = TradeId.ToString(),
                Payer = new PayerInfo { OpenId = request.OpenId }
            };
 
            var payRequest = new WeChatPayTransactionsJsApiRequest();
            payRequest.SetBodyModel(model);
            WeChatPayOptions weChatPayOptions = GetPayOptions();
            var response = await _client.ExecuteAsync(payRequest, weChatPayOptions);
            if (response.IsError)
            {
                return Error(response.Message);
            }
            wxpayTrade.PrepayId = response.PrepayId;
            //记录库
            bool re = new WxpayTradeDAL().Insert(wxpayTrade);
            if (!re)
            {
                return Error("系统异常,请联系客服!");
            }
            var req = new WeChatPayJsApiSdkRequest
            {
                Package = "prepay_id=" + response.PrepayId
            };
 
            var parameter = await _client.ExecuteAsync(req, weChatPayOptions);
 
            // 将参数(parameter)给 公众号前端
            // https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_1_4.shtml
            return Success(parameter);
        }
 
        /// <summary>
        /// 微信支付回调
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public async Task<IActionResult> WxPayBack()
        {
            try
            {
                WeChatPayOptions weChatPayOptions = GetPayOptions();
                var notify = await _notifyClient.ExecuteAsync<WeChatPayTransactionsNotify>(HttpContext.Request, weChatPayOptions);
                if (notify.TradeState == WeChatPayTradeState.Success)
                {//支付成功
 
                    LogUtil.Info(JSONUtil.ObjectToJson(notify), "结果解密");
                    //处理支付结果
                    //用户信息查询
 
                    var preTrade = new WxpayTradeDAL().GetById(notify.OutTradeNo);
                    if (preTrade.IsNull())
                    {//预支付订单不存在
                        LogUtil.Info("预支付订单不存在:" + JSONUtil.ObjectToJson(notify), "支付结果失败");
                        return WeChatPayNotifyResult.Success;
                    }
                    preTrade.BackTime = DateTime.Now;
                    preTrade.HasBack = 1;
                    preTrade.TransactionId = notify.TransactionId;
                    preTrade.TradeType = notify.TradeType;
                    preTrade.TradeState = notify.TradeState;
                    preTrade.TradeStateDesc = notify.TradeStateDesc;
                    if (!notify.SuccessTime.IsNullOrEmpty())
                    {
                        preTrade.SuccessTime = Convert.ToDateTime(notify.SuccessTime);
                    }
                    new WxpayTradeDAL().Update(preTrade, null, null);
                    //充值处理
                    PayUserInfo(notify, preTrade);
                    //发送提醒
                    try
                    {
                        string warStr = "充值提醒\n>类型:短信充值\n>短信数量:" + preTrade.SmsCount + "\n>充值金额:" + Math.Round((decimal)preTrade.Amount / 100, 2);
                        SendQwGroup.SendMessage(warStr);
                    }
                    catch
                    {
 
                    }
                    
                    return WeChatPayNotifyResult.Success;
                }
                return WeChatPayNotifyResult.Failure;
            }
            catch (WeChatPayException ex)
            {
                LogUtil.Info("ERROR:" + ex.ToString(), "结果解密");
                return WeChatPayNotifyResult.Failure;
            }
        }
 
        private void PayUserInfo(WeChatPayTransactionsNotify notify, WxpayTrade wxTrade)
        {
            var member_where_expression = Expressionable.Create<SmsMember>().And(m => m.Openid == notify.Payer.OpenId).And(m => m.Isblack == 0).ToExpression();
            var memberinfo = new SmsMemberDAL().GetSingle(member_where_expression);
            string id = string.Empty;
            if (memberinfo == null || string.IsNullOrEmpty(memberinfo.Id))
            {
 
                SmsMember smsMember = new SmsMember
                {
                    Id = Guid.NewGuid().ToString(),
                    Registertime = DateTime.Now,
                    Openid = notify.Payer.OpenId,
                    Smscount = wxTrade.SmsCount,
                    Longintime = DateTime.Now
                };
                bool issuccess_member = new SmsMemberDAL().Insert(smsMember);
                if (!issuccess_member)
                {
                    LogUtil.Info("注册失败:" + JSONUtil.ObjectToJson(notify), "支付结果失败");
                }
            }
            else
            {
                id = memberinfo.Id;
                SmsMember smsMember = new SmsMember
                {
                    Smscount = wxTrade.SmsCount + memberinfo.Smscount
                };
                int successcount = new SmsMemberDAL().Update(smsMember, m => new { m.Smscount }, s => s.Id == memberinfo.Id);
                if (successcount == 0)
                {
                    LogUtil.Info("充值失败:" + JSONUtil.ObjectToJson(notify), "支付结果失败");
                }
            }
            //新增充值记录
            decimal amount = Math.Round(decimal.Parse(wxTrade.Amount.ToString()) / 100, 2);
            SmsRecord smsRecord = new SmsRecord
            {
                Id = Guid.NewGuid().ToString(),
                Createtime = DateTime.Now,
                Rechargecount = wxTrade.SmsCount,
                Tid = notify.TransactionId,
                Rechargeamount = amount,
                Stype = 0,
                Memberid = id,
                Openid = notify.Payer.OpenId
 
            };
            bool issuccess = new SmsRecordDAL().Insert(smsRecord);
            if (!issuccess)
            {
                LogUtil.Info("充值记录新增失败:" + JSONUtil.ObjectToJson(notify), "支付结果失败");
            }
        }
 
        public static WeChatPayOptions GetPayOptions()
        {
            WeChatPayOptions weChatPayOptions = new WeChatPayOptions()
            {
                AppId = AppId,
                MchId = MchId,
                APIv3Key = APIv3Key,
                Certificate = Certificate
            };
            return weChatPayOptions;
        }
 
    }
}