public void CompleteSale() { CompleteSaleCall api = new CompleteSaleCall(this.apiContext); TransactionType tran = null; if (TestData.SellerTransactions != null && TestData.SellerTransactions.Count > 0) { tran = TestData.SellerTransactions[0]; } // Make API call. ApiException gotException = null; // Negative test. try { if (tran != null) { api.ItemID = tran.Item.ItemID; api.TransactionID = tran.TransactionID; PaymentStatusCodeType pStatus = tran.Status.eBayPaymentStatus; api.Paid = (pStatus == PaymentStatusCodeType.NoPaymentFailure) && (tran.PaidTimeSpecified); } else { api.ItemID = "TestID"; } api.Execute(); } catch (ApiException ex) { gotException = ex; } if (gotException != null) { Assert.IsNull(tran); } }
public ExpressCheckoutResult DoExpressCheckout() { HttpContext context = HttpContext.Current; TraceContext trace = context.Trace; string traceCategory = this.GetType().ToString(); ExpressCheckoutSession paypalSession = ExpressCheckoutSession.Current; if (paypalSession == null) { //EXIT WITH EXCEPTION ErrorType[] customErrorList = new ErrorType[1]; ErrorType customError = new ErrorType(); customError.ErrorCode = "SESSION"; customError.ShortMessage = "Missing Token"; customError.LongMessage = "The PayPal session token was expired or unavailable. Please try again."; customErrorList[0] = customError; return(new ExpressCheckoutResult(0, string.Empty, customErrorList)); } trace.Write(traceCategory, "Detected PayPal Token:" + paypalSession.Token); trace.Write(traceCategory, "Token Expiration:" + paypalSession.TokenExpiration.ToLongDateString()); if (string.IsNullOrEmpty(paypalSession.PayerID)) { //EXIT WITH EXCEPTION ErrorType[] customErrorList = new ErrorType[1]; ErrorType customError = new ErrorType(); customError.ErrorCode = "SESSION"; customError.ShortMessage = "Missing Payer ID"; customError.LongMessage = "The PayPal Payer ID is not present."; customErrorList[0] = customError; return(new ExpressCheckoutResult(0, string.Empty, customErrorList)); } trace.Write(traceCategory, "Detected PayPal Payer ID:" + paypalSession.PayerID); //GET THE CURRENCY FOR THE TRANSACTION string storeCurrencyCode = Token.Instance.Store.BaseCurrency.ISOCode; CurrencyCodeType baseCurrencyCode = PayPalProvider.GetPayPalCurrencyType(storeCurrencyCode); //CREATE THE EXPRESS CHECKOUT DoExpressCheckoutPaymentRequestType expressCheckoutRequest = new DoExpressCheckoutPaymentRequestType(); expressCheckoutRequest.DoExpressCheckoutPaymentRequestDetails = new DoExpressCheckoutPaymentRequestDetailsType(); expressCheckoutRequest.DoExpressCheckoutPaymentRequestDetails.Token = paypalSession.Token; expressCheckoutRequest.DoExpressCheckoutPaymentRequestDetails.PaymentAction = this.UseAuthCapture ? PaymentActionCodeType.Sale : PaymentActionCodeType.Authorization; expressCheckoutRequest.DoExpressCheckoutPaymentRequestDetails.PaymentActionSpecified = true; expressCheckoutRequest.DoExpressCheckoutPaymentRequestDetails.PayerID = paypalSession.PayerID; expressCheckoutRequest.Version = "1.0"; //SET THE ORDER TOTAL AMOUNTS Basket basket = Token.Instance.User.Basket; trace.Write(traceCategory, "Set Order Totals"); LSDecimal curOrderTotal = basket.Items.TotalPrice(); LSDecimal curShippingTotal = basket.Items.TotalPrice(OrderItemType.Shipping) + GetShippingCouponTotal(basket.Items); LSDecimal curHandlingTotal = basket.Items.TotalPrice(OrderItemType.Handling); LSDecimal curTaxTotal = basket.Items.TotalPrice(OrderItemType.Tax); LSDecimal curItemTotal = curOrderTotal - (curShippingTotal + curHandlingTotal + curTaxTotal); //MAKE SURE OUR BREAKDOWN IS VALID if ((curShippingTotal < 0) || (curHandlingTotal < 0) || (curTaxTotal < 0) || (curItemTotal < 0)) { //THE BREAKDOWN IS INVALID, DO NOT INCLUDE IT IN THE REQUEST curShippingTotal = 0; curHandlingTotal = 0; curTaxTotal = 0; curItemTotal = curOrderTotal; } //SET THE PAYMENT DETAILS expressCheckoutRequest.DoExpressCheckoutPaymentRequestDetails.PaymentDetails = new PaymentDetailsType[1]; expressCheckoutRequest.DoExpressCheckoutPaymentRequestDetails.PaymentDetails[0] = new PaymentDetailsType(); PaymentDetailsType paymentDetails = expressCheckoutRequest.DoExpressCheckoutPaymentRequestDetails.PaymentDetails[0]; paymentDetails.OrderTotal = new BasicAmountType(); paymentDetails.OrderTotal.currencyID = baseCurrencyCode; paymentDetails.OrderTotal.Value = string.Format("{0:##,##0.00}", curOrderTotal); paymentDetails.ItemTotal = new BasicAmountType(); paymentDetails.ItemTotal.currencyID = baseCurrencyCode; paymentDetails.ItemTotal.Value = string.Format("{0:##,##0.00}", curItemTotal); paymentDetails.ShippingTotal = new BasicAmountType(); paymentDetails.ShippingTotal.currencyID = baseCurrencyCode; paymentDetails.ShippingTotal.Value = string.Format("{0:##,##0.00}", curShippingTotal); paymentDetails.HandlingTotal = new BasicAmountType(); paymentDetails.HandlingTotal.currencyID = baseCurrencyCode; paymentDetails.HandlingTotal.Value = string.Format("{0:##,##0.00}", curHandlingTotal); paymentDetails.TaxTotal = new BasicAmountType(); paymentDetails.TaxTotal.currencyID = baseCurrencyCode; paymentDetails.TaxTotal.Value = string.Format("{0:##,##0.00}", curTaxTotal); trace.Write(traceCategory, "Order Total: " + curOrderTotal); trace.Write(traceCategory, "Item Total: " + curItemTotal); trace.Write(traceCategory, "Shipping Total: " + curShippingTotal); trace.Write(traceCategory, "Handling Total: " + curHandlingTotal); trace.Write(traceCategory, "Tax Total: " + curTaxTotal); //SET THE BUTTON SOURCE trace.Write(traceCategory, "Set Button Source"); paymentDetails.ButtonSource = "ablecommerce-EC"; //SET THE NOTIFY URL string notifyUrl = GetStoreUrl() + "/ProcessPayPal.ashx"; trace.Write(traceCategory, "IPN Callback URL: " + notifyUrl); paymentDetails.NotifyURL = notifyUrl; //WE HAVE ALL NECESSARY INFORMATION TO DO EXPRESS CHECKOUT //COMMIT THE ORDER BEFORE SUBMITTING THE PAYPAL TRANSACTION //CREATE THE ABLECOMMERCE PAYMENT ITEM Payment checkoutPayment = new Payment(); checkoutPayment.PaymentMethodId = GetPayPalPaymentMethodId(false); checkoutPayment.Amount = curOrderTotal; checkoutPayment.CurrencyCode = baseCurrencyCode.ToString(); //AT THIS POINT, EXECUTE THE CHECKOUT TO SUBMIT THE ORDER CheckoutRequest checkoutRequest = new CheckoutRequest(checkoutPayment); CheckoutResponse checkoutResponse = basket.Checkout(checkoutRequest); int orderId = checkoutResponse.OrderId; //LOAD THE ORDER AND RE-OBTAIN THE PAYMENT RECORD TO AVOID DATA INCONSISTENCIES Order order = OrderDataSource.Load(orderId); if (order == null) { //EXIT WITH EXCEPTION ErrorType[] customErrorList = new ErrorType[1]; ErrorType customError = new ErrorType(); customError.ErrorCode = "ORDER"; customError.ShortMessage = "Your order could not be completed at this time."; customError.LongMessage = "Your order could not be completed at this time and payment was not processed. " + string.Join(" ", checkoutResponse.WarningMessages.ToArray()); customErrorList[0] = customError; return(new ExpressCheckoutResult(0, string.Empty, customErrorList)); } int findPaymentId = checkoutPayment.PaymentId; foreach (Payment payment in order.Payments) { if (payment.PaymentId == findPaymentId) { checkoutPayment = payment; } } //SET THE DESCRIPTION paymentDetails.OrderDescription = "Order #" + order.OrderNumber.ToString(); paymentDetails.Custom = orderId.ToString(); //EXECUTE PAYPAL REQUEST trace.Write(traceCategory, "Do Request"); DoExpressCheckoutPaymentResponseType expressCheckoutResponse = (DoExpressCheckoutPaymentResponseType)SoapCall("DoExpressCheckoutPayment", expressCheckoutRequest); ErrorType[] responseErrors = null; PaymentStatus finalPaymentStatus = PaymentStatus.Unprocessed; bool isPendingeCheck = false; if (expressCheckoutResponse != null) { if (expressCheckoutResponse.Errors == null) { //CREATE THE PAYPAL TRANSACTION RECORD Transaction checkoutTransaction = new Transaction(); PaymentInfoType paymentInfo = expressCheckoutResponse.DoExpressCheckoutPaymentResponseDetails.PaymentInfo[0]; isPendingeCheck = (paymentInfo.PaymentStatus == PaymentStatusCodeType.Pending && paymentInfo.PendingReason == PendingStatusCodeType.echeck); PaymentStatusCodeType paymentStatus = paymentInfo.PaymentStatus; switch (paymentStatus) { case PaymentStatusCodeType.Completed: case PaymentStatusCodeType.Processed: case PaymentStatusCodeType.Pending: if (isPendingeCheck) { finalPaymentStatus = PaymentStatus.CapturePending; checkoutTransaction.ResponseCode = "PENDING"; checkoutTransaction.ResponseMessage = "echeck"; } else { finalPaymentStatus = (paymentStatus != PaymentStatusCodeType.Pending) ? PaymentStatus.Captured : PaymentStatus.Authorized; } checkoutTransaction.TransactionStatus = TransactionStatus.Successful; break; default: finalPaymentStatus = PaymentStatus.Unprocessed; checkoutTransaction.TransactionStatus = TransactionStatus.Failed; checkoutTransaction.ResponseCode = expressCheckoutResponse.Ack.ToString(); checkoutTransaction.ResponseMessage = paymentStatus.ToString().ToUpperInvariant(); break; } checkoutTransaction.TransactionType = this.UseAuthCapture ? TransactionType.Capture : TransactionType.Authorize; checkoutTransaction.Amount = AlwaysConvert.ToDecimal(paymentInfo.GrossAmount.Value, (Decimal)curOrderTotal); checkoutTransaction.AuthorizationCode = paymentInfo.TransactionID; checkoutTransaction.AVSResultCode = "U"; checkoutTransaction.ProviderTransactionId = paymentInfo.TransactionID; checkoutTransaction.Referrer = context.Request.ServerVariables["HTTP_REFERER"]; checkoutTransaction.PaymentGatewayId = this.PaymentGatewayId; checkoutTransaction.RemoteIP = context.Request.ServerVariables["REMOTE_ADDR"]; checkoutPayment.Transactions.Add(checkoutTransaction); //FIND THE WAITING FOR IPN TRANSACTION AND REMOVE int i = checkoutPayment.Transactions.Count - 1; while (i >= 0) { if (string.IsNullOrEmpty(checkoutPayment.Transactions[i].AuthorizationCode)) { checkoutPayment.Transactions.DeleteAt(i); } i--; } } else { //SOME SORT OF ERROR ATTEMPTING CHECKOUT responseErrors = expressCheckoutResponse.Errors; } } else { //NO RESPONSE, GENERATE CUSTOM ERROR responseErrors = new ErrorType[1]; ErrorType customError = new ErrorType(); customError.ErrorCode = "NORESP"; customError.ShortMessage = "No Response From Server"; customError.LongMessage = "The PayPal service is unavailable at this time."; responseErrors[0] = customError; } trace.Write(traceCategory, "Do Request Done"); //ERRORS IN RESPONSE? if ((responseErrors != null) && (responseErrors.Length > 0)) { //CREATE THE PAYPAL TRANSACTION RECORD FOR ERROR Transaction checkoutTransaction = new Transaction(); finalPaymentStatus = PaymentStatus.Unprocessed; checkoutTransaction.TransactionStatus = TransactionStatus.Failed; checkoutTransaction.Amount = curOrderTotal; checkoutTransaction.AuthorizationCode = string.Empty; checkoutTransaction.Referrer = context.Request.ServerVariables["HTTP_REFERER"]; checkoutTransaction.PaymentGatewayId = this.PaymentGatewayId; checkoutTransaction.RemoteIP = context.Request.ServerVariables["REMOTE_ADDR"]; checkoutTransaction.ResponseCode = responseErrors[0].ShortMessage; checkoutTransaction.ResponseMessage = responseErrors[0].LongMessage; checkoutPayment.Transactions.Add(checkoutTransaction); } //MAKE SURE PAYMENT STATUS IS CORRECT checkoutPayment.ReferenceNumber = paypalSession.Payer; checkoutPayment.PaymentStatus = finalPaymentStatus; if (isPendingeCheck) { checkoutPayment.PaymentStatusReason = "echeck"; } //RECALCULATE THE ORDER STATUS (BUG 6384) AND TRIGGER PAYMENT EVENTS (BUG 8650) order.Save(true, true); //CLEAR THE TOKENS SET IN SESSION paypalSession.Delete(); return(new ExpressCheckoutResult(orderId, string.Empty, responseErrors)); }