Ejemplo n.º 1
0
        /// <summary>
        /// Makes a transaction when there exist a verified agreement between the client and the merchant.
        /// In case of payment failure: Please use a minimum of 30 minutes delay between the first try and the second. If the
        /// transaction still fails, please wait a couple of hours before the next try. After a total period of 8 hours, you should
        /// stop trying to charge the customer.
        /// Documentation: http://www.payexpim.com/technical-reference/pxagreement/autopay/
        /// </summary>
        /// <param name="request">The parameters to the AutoPay request</param>
        public async Task <AutoPayResult> AutoPay(AutoPayRequest request)
        {
            // Validation
            if (request == null)
            {
                throw new ArgumentNullException(nameof(request), "request is required");
            }

            // Build string for md5 including all fields except empty strings and description field
            var hashInput = new StringBuilder();

            hashInput.Append(Account.AccountNumber);
            hashInput.Append(request.AgreementRef);
            hashInput.Append(request.Amount.ToPayEx());
            hashInput.Append(request.ProductNumber);
            hashInput.Append(request.Description);
            hashInput.Append(request.OrderID);
            hashInput.Append(request.PurchaseOperation.ToPayEx());
            hashInput.Append(request.CurrencyCode);
            // Add encryption key at the end of string to be hashed
            hashInput.Append(Account.EncryptionKey);
            // Create a hash string from the parameters
            string hash;

            MD5Hash.Hash(hashInput.ToString(), out hash);

            // Invoke Initialize method on external PayEx PxOrder web service
            var payexAgreement = GetPxAgreementClient();
            var xmlReturn      = await payexAgreement.AutoPay3Async(
                Account.AccountNumber,
                request.AgreementRef ?? "",
                request.Amount.ToPayEx(),
                request.ProductNumber ?? "",
                request.Description ?? "",
                request.OrderID ?? "",
                request.PurchaseOperation.ToPayEx(),
                request.CurrencyCode ?? "",
                hash);

            // Parse the result
            var result = ResultParser.ParseAutoPayResult(xmlReturn);

            return(result);
        }
        /// <summary>
        /// This method is always invoked right before a customer places an order.
        /// Use it when you need to process a payment before an order is stored into database.
        /// For example, capture or authorize credit card. Usually this method is used when a customer
        /// is not redirected to third-party site for completing a payment and all payments
        /// are handled on your site (for example, PayPal Direct).
        /// </summary>
        /// <param name="processPaymentRequest">Payment info required for an order processing</param>
        /// <returns>Process payment result</returns>
        public ProcessPaymentResult ProcessPayment(ProcessPaymentRequest processPaymentRequest)
        {
            var result = new ProcessPaymentResult();

            result.NewPaymentStatus = PaymentStatus.Pending;

            // Use an existing agreement to make the payment, if the customer chose this option.
            if (!processPaymentRequest.CustomValues.TryGetValue(AgreementRefKey, out object agreementRefObject) ||
                agreementRefObject == null)
            {
                return(result);
            }

            var agreementRef = TryGetAgreementRef(processPaymentRequest.CustomValues);

            if (!string.IsNullOrEmpty(agreementRef) &&
                agreementRef != "new")
            {
                string currencyCode = _currencyService.GetCurrencyById(_currencySettings.PrimaryStoreCurrencyId)
                                      .CurrencyCode;
                string         description = string.Format("{0} - Order", _storeContext.CurrentStore.Name);
                AutoPayRequest request     = new AutoPayRequest
                {
                    PurchaseOperation = GetPurchaseOperation(),
                    Amount            = processPaymentRequest.OrderTotal,
                    CurrencyCode      = currencyCode,
                    OrderID           = processPaymentRequest.OrderGuid.ToString(),
                    ProductNumber     = "ncOrder",
                    Description       = description,
                    AgreementRef      = agreementRef,
                };
                PayexInterface payex         = GetPayexInterface();
                AutoPayResult  autopayResult = payex.AutoPay(request).GetAwaiter().GetResult();

                // Check result and set new payment status
                if (autopayResult.IsTransactionSuccessful)
                {
                    result.SubscriptionTransactionId = agreementRef;
                    if (autopayResult.TransactionStatus.Value == Enumerations.TransactionStatusCode.Authorize)
                    {
                        result.NewPaymentStatus               = PaymentStatus.Authorized;
                        result.AuthorizationTransactionId     = autopayResult.TransactionNumber;
                        result.AuthorizationTransactionResult = autopayResult.ErrorCode;
                    }
                    else if (autopayResult.TransactionStatus.Value == Enumerations.TransactionStatusCode.Sale)
                    {
                        result.NewPaymentStatus         = PaymentStatus.Paid;
                        result.CaptureTransactionId     = autopayResult.TransactionNumber;
                        result.CaptureTransactionResult = autopayResult.ErrorCode;
                    }
                }
                else
                {
                    _logger.Error(
                        string.Format("PayEx: AutoPay failed for order {0}.", processPaymentRequest.OrderGuid),
                        new NopException(autopayResult.GetErrorDescription()));
                }
            }

            return(result);
        }