H5网站接入Paypal支付接口

写本文章的目的是为了记录工作中遇到的问题,方便以后遇到可以迅速解决问题

paypal支付接口实现由几种方法,我使用的是REST API

所以在这里值介绍这种方法的使用

我们使用vs的Nuget下载Paypal的dll

首先需要配置Web.config文件

1.在configuration节点下配置configsections中的section节点

2.在configuration节点下配置paypal节点

<configuration> 
<configSections> <!--IMPORTANT: Make sure you add the configSections node to your config file so that the rest of the config file is picked by the application--> <section name="paypal" type="PayPal.SDKConfigHandler, PayPal" /> <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" /> </configSections>
  <paypal>
    <settings>
      <!-- Replace the mode to `security-test-sandbox` to test if your server supports TLSv1.2. For more information follow README instructions.-->
      <add name="mode" value="sandbox" />
      <add name="connectionTimeout" value="360000" />
      <add name="requestRetries" value="1" />
      <add name="clientId" value="ATnMWGSD5FAe8_kd5eA83ZN5V5jiRY57CCqYUG6We3uDrIfZNSolS_CZ0DK2I74yf03IEcN8HgMIl3Md" />
      <add name="clientSecret" value="ENW9z0srkaWrowK5BQif52xHJoDoTaqZU38bz-y0mAz37sHDD9okHubjPcr0gmkZtlR9MbVuMshl_hyX" />
    </settings>
  </paypal>
</configuration>

clientid,和clientSecret的值需要自己在沙箱中配置,才能得到

用户点击付款按钮时,调用这个方法

引用命名空间

using PayPal.Api;

 public ActionResult PaypalPayment(string orderNo)
        {
            try
            {
                var config = ConfigManager.Instance.GetProperties();//读取配置文件
                var accessToken = new OAuthTokenCredential(config).GetAccessToken();
                var apiContext = new APIContext(accessToken);
                string payerId = Request.Params["PayerID"];//用户登录账号付款后,这个payerid才有值
                if (string.IsNullOrEmpty(payerId))//还没有登陆付款
                {
                    PaypalTradeWayPayServer pay = new PaypalTradeWayPayServer();
                    var approvalUrl = pay.payment(orderNo, Request, Session, apiContext);//发送给paypal的参数方法
                    if (!string.IsNullOrEmpty(approvalUrl))
                    {
                        return Redirect(approvalUrl);
                    }
                    else
                    {
                        return RedirectToAction("Error404", "MPublic", null);
                    }
                }
                else
                {
var guid = Request.Params["guid"];//登陆付款后才进入这里 // Using the information from the redirect, setup the payment to execute. var paymentId = Session[guid] as string; var paymentExecution = new PaymentExecution() { payer_id = payerId }; var payment = new Payment() { id = paymentId }; // Execute the payment. var executedPayment = payment.Execute(apiContext, paymentExecution); ViewBag.result = "success"; } } catch (PayPal.PayPalException ex) { //插入错误日志 } return View("PayResult"); }

payment方法:

具体参数请自行查看

/// <summary>
        /// 得到ItemList
        /// </summary>
        /// <param name="order"></param>
        /// <returns></returns>
        public string payment(string orderNo, HttpRequest Request,HttpSessionStateBase Session, APIContext apiContext)
        {
            // ###Items
            // Items within a transaction.
            var order = Context.Data.Order.Where(x=>x.OrderNo== orderNo && x.Del==false &&x.PayType== Interface.Order.Eum.EumPayType.Paypal).ToEntity();
            var orderDetail = Context.Data.OrderDetail.Where(x => x.OrderNo == orderNo).ToSelectList(x => new { Num = x.Num.ToString(), SkuPrice = x.SkuPrice, SkuName = x.SkuName,UnitName=x.UnitName });
            if (order == null || orderDetail == null)
            {
                return "";
            }
            var items = new List<Item>();
            string myCurrency = ChangeCurrency(order.CurrencyCode.Trim());
            foreach (var detail in orderDetail)
            {
                var item = new Item { name = detail.SkuName, price = detail.SkuPrice.ToString(), quantity = detail.Num, currency=myCurrency,sku= detail.UnitName };
                items.Add(item);
            }
            var itemList = new ItemList() { items = items };
            var payer = new Payer() { payment_method = "paypal" };

            // ###Redirect URLS
            // These URLs will determine how the user is redirected from PayPal once they have either approved or canceled the payment.
            string baseURI = Request.Url.Scheme + "://" + Request.Url.Authority + "/WebPay/PaypalPayment?";//支付完成后返回的地址
            var guid = Convert.ToString((new Random()).Next(100000));
            var redirUrls = new RedirectUrls()
            {
                cancel_url = baseURI + "guid=" + guid,
                return_url = baseURI + "guid=" + guid
            };
            
            // ###Details
            // Let's you specify details of a payment amount.
            var details = new Details()
            {
                tax = "0.00",
                shipping = order.TotalFreight.Value.ToString(),
                subtotal = order.TotalAmount.Value.ToString()
            };

            // ###Amount
            // Let's you specify a payment amount.
            var amount = new Amount()
            {
                currency = myCurrency,
                total = (order.TotalAmount.Value + order.TotalFreight.Value).ToString(), // Total must be equal to sum of shipping, tax and subtotal.
                details = details
            };

            // ###Transaction
            // A transaction defines the contract of a
            // payment - what is the payment for and who
            // is fulfilling it. 
            var transactionList = new List<Transaction>();

            // The Payment creation API requires a list of
            // Transaction; add the created `Transaction`
            // to a List
            string address = Request.Url.Scheme + "://" + Request.Url.Authority;
            transactionList.Add(new Transaction()
            {
                description = "Transaction description.",
                amount = amount,
                item_list = itemList,
                 custom=order.OrderNo,//这个参数可以传递我们的需要的参数,这里我传的是订单号
                  notify_url= address+"/WebPay/Receive"//接收Paypal的IPN消息地址,必须需要外网可以访问
            });

            // ###Payment
            // A Payment Resource; create one using
            // the above types and intent as `sale` or `authorize`
            var payment = new Payment()
            {
                intent = "sale",
                payer = payer,
                transactions = transactionList,
                redirect_urls = redirUrls               
            };

            try
            {
                // Create a payment using a valid APIContext
                var createdPayment = payment.Create(apiContext);

                // Using the `links` provided by the `createdPayment` object, we can give the user the option to redirect to PayPal to approve the payment.
                var links = createdPayment.links.GetEnumerator();
                string approvalUrl = "";
                while (links.MoveNext())
                {
                    var link = links.Current;
                    if (link.rel.ToLower().Trim().Equals("approval_url"))
                    {
                        approvalUrl = link.href;
                    }
                }
                Session.Add(guid, createdPayment.id);
                Session.Add("orderNo", orderNo);
                return approvalUrl;
            }
            catch (PayPal.PayPalException ex)
            {
                //插入错误日志

            }
            return "";
        }

到这里支付请求就已经完成了,但修改订单状态和操作数据库的语句我们写到Paypal的IPN中执行

 private string myEmail = "953478297@qq.com";
        /// <summary>
        ///接收Paypal的IPN消息
        /// </summary>
        /// <returns></returns>
       [HttpPost]
        public HttpStatusCodeResult Receive()
        {//Store the IPN received from PayPal
            LogRequest(Request);
            //Fire and forget verification task
            Task.Run(() => VerifyTask(Request));

            //Reply back a 200 code
            return new HttpStatusCodeResult(HttpStatusCode.OK);
        }
        /// <summary>
        /// 验证是否是paypal发过来的消息
        /// </summary>
        /// <param name="ipnRequest"></param>

        private void VerifyTask(HttpRequest ipnRequest)
        {
            var verificationResponse = string.Empty;try
            {
                System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
                var verificationRequest = (HttpWebRequest)WebRequest.Create("https://www.sandbox.paypal.com/cgi-bin/webscr");

                //Set values for the verification request
                verificationRequest.Method = "POST";
                verificationRequest.ContentType = "application/x-www-form-urlencoded";
                var param = Request.BinaryRead(ipnRequest.ContentLength);
                var strRequest = Encoding.ASCII.GetString(param);

                //Add cmd=_notify-validate to the payload
                strRequest = "cmd=_notify-validate&" + strRequest;
                verificationRequest.ContentLength = strRequest.Length;

                //Attach payload to the verification request
                var streamOut = new StreamWriter(verificationRequest.GetRequestStream(), Encoding.ASCII);
                streamOut.Write(strRequest);
                streamOut.Close();

                //Send the request to PayPal and get the response
                var streamIn = new StreamReader(verificationRequest.GetResponse().GetResponseStream());
                verificationResponse = streamIn.ReadToEnd();
                streamIn.Close();
                ProcessVerificationResponse(verificationResponse, ipnRequest);
            }
            catch (Exception exception)
            {//插入错误日志
                ErrorLogPO errorLog = new ErrorLogPO();
                errorLog.KID = Guid.NewGuid();
                errorLog.ErrorMessage = exception.Message;
                errorLog.ErrorState = Interface.Offer.Eum.EumErrorLogType.Paypal;
                errorLog.OperaTime = DateTime.Now;
                errorLog.Del = false;
                OfferServer.ErrorLog.AddErrorLog(errorLog);
            }         
        }
        /// <summary>
        /// 记录txn_id和状态验证重复
        /// </summary>
        /// <param name="request"></param>
        private void LogRequest(HttpRequest request)
        {
            //交易状态
            string payment_status = request.Form["payment_status"].ToString();//交易号
            string txn_id = request.Form["txn_id"].ToString();

            // Persist the request values into a database or temporary data store
            PaypalTradeWayPayServer pay = new PaypalTradeWayPayServer();
            pay.OneCreate(payment_status, txn_id);
        }
        /// <summary>
        /// 执行业务操作
        /// </summary>
        /// <param name="verificationResponse"></param>
        /// <param name="request"></param>
        private void ProcessVerificationResponse(string verificationResponse, HttpRequest request)
        {
            try
            {
                if (verificationResponse.Equals("VERIFIED"))
                {
                    // check that Payment_status=Completed
                    // check that Txn_id has not been previously processed
                    // check that Receiver_email is your Primary PayPal email
                    // check that Payment_amount/Payment_currency are correct
                    // process payment      
                    //NameValueCollection coll;
                    ////Load Form variables into NameValueCollection variable.
                    //coll = Request.Form;

                    //// Get names of all forms into a string array.
                    //String[] requestItem = coll.AllKeys;

                    //for (var i = 0; i < requestItem.Length; i++)
                    //{
                    //    WriteError(requestItem[i] + ":" + Request.Form[requestItem[i]]);
                    //}
                    //卖方邮箱
                    string receiver_email = request.Form["receiver_email"].ToString();
                    //交易状态
                    string payment_status = request.Form["payment_status"].ToString();
                    //交易号
                    string txn_id = request.Form["txn_id"].ToString();
                    string mc_gross = request.Form["mc_gross"].ToString();//金额
                    string mc_currency = request.Form["mc_currency"].ToString();//货币                          
                    // DateTime Payment_date = Convert.ToDateTime(request.Form["payment_date"].ToString());//交易时间
                    DateTime Payment_date = DateTime.Now;
                    //订单号
                    string custom = request.Form["custom"].ToString();if (payment_status == "Completed")
                    {
                        PaypalWayPayPO model = PayWayServer.PaypalWayPay.Find(x => x.Txn_id == txn_id.Trim());
                        var order = OrderServer.Order.Find(x => x.OrderNo == custom.Trim());
                        PaypalTradeWayPayServer pay = new PaypalTradeWayPayServer();
                        bool verity = model.Payment_status == payment_status && receiver_email == myEmail && (order.TotalAmount.Value + order.TotalFreight.Value).ToString() == mc_gross && pay.ChangeCurrency(order.CurrencyCode.Trim()) == mc_currency;if (verity)
                        {                         
                            pay.UpdatePaypalData(Payment_date, custom, txn_id, payment_status);
                        }
                    }
                }
                else if (verificationResponse.Equals("INVALID"))
                {
                    string custom1 = request.Form["custom"].ToString();
                    ErrorLogPO model = new ErrorLogPO();
                    model.KID = Guid.NewGuid();
                    model.ErrorState = EumErrorLogType.Paypal;
                    model.ErrorMessage = "Paypal支付订单号为:" + custom1 + "状态无效";
                    model.OperaTime = DateTime.Now;
                    model.Del = false;
                    OfferServer.ErrorLog.AddErrorLog(model);
                }
                else
                {
                    ErrorLogPO model = new ErrorLogPO();
                    model.KID = Guid.NewGuid();
                    model.ErrorState = EumErrorLogType.Paypal;
                    model.ErrorMessage = "Palpal请求失败";
                    model.OperaTime = DateTime.Now;
                    model.Del = false;
                    OfferServer.ErrorLog.AddErrorLog(model);
                }
            }
            catch (Exception ex)
            {
                ErrorLogPO model = new ErrorLogPO();
                model.KID = Guid.NewGuid();
                model.ErrorState = EumErrorLogType.Paypal;
                model.ErrorMessage = ex.Message;
                model.OperaTime = DateTime.Now;
                model.Del = false;
                OfferServer.ErrorLog.AddErrorLog(model);
            }
        }

 

posted @ 2017-05-12 16:21  勤奋的小鑫0  阅读(8014)  评论(2编辑  收藏  举报