Я использую PayPalMerchantSDK для интеграции корзины.
В качестве ответа я использую этот сценарий, так как мне нужно отправить корзину в PayPal с помощью кнопки экспресс-оплаты. Также в моей корзине есть купон на скидку, который можно использовать на общую сумму. Я использую решения Asp.Net MVC
Пожалуйста, следуйте коду и инструкциям для интеграции платежей PayPal.
Шаг 1: Скачать и отослать PayPal_Merchant_SDK.dll
Шаг 2: Добавьте необходимые настройки в свой файл web.config для обслуживания PayPal_Merchant_SDK
Шаг 3: В вашем контроллере корзины Действие оплаты добавьте следующий код
[HttpPost]
public ActionResult Payment()
{
var basketForPayment = GetBasket();
if (basketForPayment.Order == null || basketForPayment.OrderItem.Count <= 0 || basketForPayment.Order.DVEcomOrderStatus.ID != (int)DvEcomOrderStatusEnum.Initiated) { return View("basket-empty", new DvClientViewModel(UrlBasketEmptyPage, Languages.English)); }
//Paypal Expresscheckout Integration===============================
// Step 1: Create the paypal request object
var request = new SetExpressCheckoutRequestType();
PopulatePaypalRequestObject(request, basketForPayment);
// Step 2: Invoke the API
SetExpressCheckoutReq getTockenWrapper = new SetExpressCheckoutReq();
getTockenWrapper.SetExpressCheckoutRequest = request;
PayPalAPIInterfaceServiceService service = new PayPalAPIInterfaceServiceService();
SetExpressCheckoutResponseType setEcResponse = service.SetExpressCheckout(getTockenWrapper);
// Step 3: Check for API return status and get the payment tocken
HttpContext currContext = System.Web.HttpContext.Current;
currContext.Items.Add("paymentDetails", request.SetExpressCheckoutRequestDetails.PaymentDetails);
var currResponseContext = SetPayPalKeyResponseObjects(service, setEcResponse);
var responseobject = (Dictionary<string, string>) currResponseContext.Items["Response_keyResponseObject"];
if (responseobject["API Status"] != "SUCCESS")
{
return View("Invalid-basket", new DvClientViewModel(UrlBasketEmptyPage, Languages.English));
}
//Step 4: Make Payment with the tocken
var tocken = responseobject["EC token"];
string queryString = "https://www.sandbox.paypal.com/webscr?cmd=_express-checkout";
if(!string.IsNullOrEmpty(tocken))
{
//Update Order with the transaction token
_orderRepository.UpdateOrder(model.Order.OrderNumber, tocken);
queryString += string.Format("&token={0}", tocken);
Response.Redirect(queryString);
}
return RedirectToAction("Payment");
}
Шаг 4: Действие ответа на Ваш платеж
public ActionResult PaymentResponse()
{
// If we have a SECURE_SECRET then validate the incoming data using the MD5 hash
//included in the incoming data
if (Request.QueryString["token"].Length > 0 && Request.QueryString["PayerID"].Length > 0 )
{
var token = Request.QueryString["token"];
var payerId = Request.QueryString["PayerID"];
var order = _orderRepository.GetOrderTransaction(token);
if(order !=null)
{
//Update Order with the transaction token
_orderRepository.UpdateOrderSuccess(order.OrderNumber, token, payerId);
}
PaymentResponseClearSessionAndCookie();
Response.Redirect("/");
}
return View("Invalid-basket", new DvClientViewModel(UrlBasketEmptyPage, Languages.English));
}
Шаг 5: Подготовить корзину для PayPal
private void PopulatePaypalRequestObject(SetExpressCheckoutRequestType request, DvEcomOrderViewModel basket)
{
var ecDetails = new SetExpressCheckoutRequestDetailsType();
ecDetails.ReturnURL = ConfigurationManager.AppSettings["PayPalReturnUrl"]; ecDetails.CancelURL = ConfigurationManager.AppSettings["PayPalCancelUrl"]; ecDetails.BuyerEmail = basket.Order.CustomerEmailAddress;
//Fix for release
ecDetails.AddressOverride = "0";
ecDetails.NoShipping = "1";
/* Populate payment requestDetails.
* SetExpressCheckout allows parallel payments of upto 10 payments.
* This samples shows just one payment.
*/
var paymentDetails = new PaymentDetailsType();
ecDetails.PaymentDetails.Add(paymentDetails);
double orderTotal = 0.0;
double itemTotal = 0.0;
var currency = (CurrencyCodeType)
Enum.Parse(typeof(CurrencyCodeType), ConfigurationManager.AppSettings["PayPalCurrency"]);
paymentDetails.OrderTotal = new BasicAmountType(currency, orderTotal.ToString(CultureInfo.InvariantCulture));
orderTotal += Double.Parse(basket.Order.SubTotal.ToString(CultureInfo.InvariantCulture)); // Subtotal
paymentDetails.ShippingTotal = new BasicAmountType(currency, basket.Order.DeliveryAmount.ToString(CultureInfo.InvariantCulture)); // Add delivery charge
orderTotal += Double.Parse(basket.Order.DeliveryAmount.ToString(CultureInfo.InvariantCulture));
paymentDetails.TaxTotal = new BasicAmountType(currency, basket.Order.VAT.ToString(CultureInfo.InvariantCulture)); //Add Vat Tax
orderTotal += Double.Parse(basket.Order.VAT.ToString(CultureInfo.InvariantCulture));
//paymentDetails.ShippingDiscount = new BasicAmountType(currency, basket.Order.DiscountAmount.ToString(CultureInfo.InvariantCulture)); // Subtract discount
orderTotal -= Double.Parse(basket.Order.DiscountAmount.ToString(CultureInfo.InvariantCulture));
paymentDetails.OrderDescription = string.Format("Payment for the basket order {0}", basket.Order.OrderNumber);
paymentDetails.PaymentAction = (PaymentActionCodeType)
Enum.Parse(typeof(PaymentActionCodeType), "SALE");
AddressType shipAddress = new AddressType();
shipAddress.Name = string.Format("{0} {1}", basket.Order.DeliveryFirstName, basket.Order.DeliverySurname);
shipAddress.Street1 = basket.Order.BillingAddress1;
shipAddress.Street2 = basket.Order.BillingAddress2 ?? "-";
shipAddress.CityName = basket.Order.DeliveryTown ?? "-";
shipAddress.StateOrProvince = basket.Order.DeliveryCounty;
shipAddress.Country = (CountryCodeType)
Enum.Parse(typeof(CountryCodeType), "GB");
shipAddress.PostalCode = basket.Order.DeliveryPostcode;
//Fix for release
shipAddress.Phone = basket.Order.DeliveryTelePhone;
ecDetails.PaymentDetails[0].ShipToAddress = shipAddress;
// Each payment can include requestDetails about multiple items
// This example shows just one payment item
//ApplyDiscount
if (basket.Order.DiscountAmount > 0)
{
decimal disAmt = basket.Order.DiscountAmount -
(basket.Order.DiscountAmount + basket.Order.DiscountAmount);
PaymentDetailsItemType discount = new PaymentDetailsItemType();
discount.Amount = new BasicAmountType(currency, disAmt.ToString(CultureInfo.InvariantCulture));
discount.Description = "Discount Applied";
discount.Name = "Voucher Code";
paymentDetails.PaymentDetailsItem.Add(discount);
}
var itemDetails = new PaymentDetailsItemType();
foreach (var item in basket.OrderItem)
{
itemDetails.Name = item.ProductName;
itemDetails.Amount = new BasicAmountType(currency, item.UnitPrice.ToString(CultureInfo.InvariantCulture));
itemDetails.Quantity = Int32.Parse(item.Quantity.ToString(CultureInfo.InvariantCulture));
itemDetails.ItemCategory = (ItemCategoryType)
Enum.Parse(typeof(ItemCategoryType), "0");
itemTotal += Double.Parse(item.UnitPrice.ToString(CultureInfo.InvariantCulture)) * itemDetails.Quantity.Value;
itemDetails.Tax = new BasicAmountType(currency, item.VAT.ToString(CultureInfo.InvariantCulture));
itemDetails.Description = item.ProductName;
paymentDetails.PaymentDetailsItem.Add(itemDetails);
}
itemTotal -= Double.Parse(basket.Order.DiscountAmount.ToString(CultureInfo.InvariantCulture));
paymentDetails.ItemTotal = new BasicAmountType(currency, itemTotal.ToString(CultureInfo.InvariantCulture));
paymentDetails.OrderTotal = new BasicAmountType(currency, orderTotal.ToString(CultureInfo.InvariantCulture));
request.SetExpressCheckoutRequestDetails = ecDetails;
}
Шаг 6: Вам больше нечего начинать с ...
Шаг 7. Приведенные выше шаги приведут вас к успешному переводу PayPal. Затем вам нужно авторизовать реальную транзакцию через другой вызов API Paypal Authorize через метод Post. Процесс такой же, как описанный выше.