/// <summary> /// Handles a payment request /// </summary> /// <returns>Returns the id of the created request</returns> public async Task <string> HandleRequest(IPaymentRequest request) { _logger?.LogTrace($"Processing request '{request.Id}'"); // Persist request to local repository var id = _repository.Create(request); if (request == null) { throw new ArgumentNullException(nameof(request)); } // Validate request if (!_validator.Validate(request, out var reasons)) { throw new InvalidDataException(reasons); } // Post to bank await _bankService.Post(request); // Mark as successfully processed _repository.UpdateResult(request.Id, true); return(id); }
private void SetSettings(IPaymentRequest request) { // do the common stuff // ... // set custom settings OnSetSettings(request); }
public async Task <IActionResult> GetDetailsAsync(string merchantId, string paymentRequestId) { try { IPaymentRequest paymentRequest = await _paymentRequestService.GetAsync(merchantId, paymentRequestId); if (paymentRequest == null) { return(NotFound(ErrorResponse.Create("Could not find payment request"))); } PaymentRequestRefund refundInfo = await _paymentRequestService.GetRefundInfoAsync(paymentRequest.WalletAddress); PaymentRequestDetailsModel model = await _paymentRequestDetailsBuilder.Build < PaymentRequestDetailsModel, PaymentRequestOrderModel, PaymentRequestTransactionModel, PaymentRequestRefundModel>(paymentRequest, refundInfo); return(Ok(model)); } catch (Exception ex) { await _log.WriteErrorAsync(nameof(GetDetailsAsync), new { MerchantId = merchantId, PaymentRequestId = paymentRequestId }.ToJson(), ex); throw; } }
public async Task <IActionResult> ChechoutAsync([FromBody] ChechoutRequestModel model) { try { IPaymentRequest paymentRequest = await _paymentRequestService.CheckoutAsync(model.MerchantId, model.PaymentRequestId, model.Force); IOrder order = await _orderService.GetAsync(paymentRequest.Id, paymentRequest.OrderId); return(Ok(Mapper.Map <OrderModel>(order))); } catch (AssetUnknownException assetEx) { await _log.WriteErrorAsync(nameof(OrdersController), nameof(ChechoutAsync), new { assetEx.Asset }.ToJson(), assetEx); return(BadRequest(ErrorResponse.Create(assetEx.Message))); } catch (MarkupNotFoundException markupEx) { await _log.WriteErrorAsync(nameof(OrdersController), nameof(ChechoutAsync), new { markupEx.MerchantId, markupEx.AssetPairId }.ToJson(), markupEx); return(BadRequest(ErrorResponse.Create(markupEx.Message))); } catch (Exception ex) { await _log.WriteErrorAsync(nameof(OrdersController), nameof(ChechoutAsync), model.ToJson(), ex); throw; } }
public async Task <PaymentRequestRefund> GetRefundInfoAsync(string walletAddress) { IReadOnlyList <IPaymentRequestTransaction> transactions = (await _transactionsService.GetByWalletAsync(walletAddress)).Where(x => x.IsRefund()).ToList(); if (!transactions.Any()) { return(null); } IEnumerable <string> transferIds = transactions.Unique(x => x.TransferId).ToList(); if (transferIds.MoreThanOne()) { throw new MultiTransactionRefundNotSupportedException(); } Transfer transfer = await _transferService.GetAsync(transferIds.Single()); IPaymentRequest paymentRequest = await FindAsync(walletAddress); return(new PaymentRequestRefund { Amount = transfer.Amounts.Sum(x => x.Amount ?? 0), Timestamp = transfer.CreatedOn, Address = transfer.Amounts.Unique(x => x.Destination).Single(), DueDate = transactions.OrderByDescending(x => x.DueDate).First().DueDate ?? paymentRequest.DueDate, Transactions = Mapper.Map <IEnumerable <PaymentRequestRefundTransaction> >(transactions) }); }
/// <summary> /// Start the paypal payment process. This should return a redirect url in the IPaymentResponse. /// </summary> /// <param name="request"></param> /// <returns></returns> private IPaymentResponse BeginExpressCheckout(IPaymentRequest request) { var response = new PaymentResponse(); try { SetExpressCheckoutRequestDetailsType reqDetails = new SetExpressCheckoutRequestDetailsType(); reqDetails.ReturnURL = request.PaymentSuccessReturnUrl.ToString(); reqDetails.CancelURL = request.PaymentCancelReturnUrl.ToString(); reqDetails.NoShipping = "1"; reqDetails.PaymentAction = PaymentActionCodeType.Sale; reqDetails.PaymentActionSpecified = true; reqDetails.AllowNote = "0"; BillingAgreementDetailsType bADT = new BillingAgreementDetailsType() { BillingAgreementDescription = string.Empty, BillingType = BillingCodeType.RecurringPayments }; reqDetails.BillingAgreementDetails = new BillingAgreementDetailsType[1]; reqDetails.BillingAgreementDetails.SetValue(bADT, 0); reqDetails.OrderTotal = new BasicAmountType() { currencyID = CurrencyCodeType.USD, Value = request.Amount.ToString() }; bADT.BillingAgreementDescription = request.Description; reqDetails.OrderDescription = bADT.BillingAgreementDescription; SetExpressCheckoutReq req = new SetExpressCheckoutReq() { SetExpressCheckoutRequest = new SetExpressCheckoutRequestType() { Version = this._paymentGateway.APIVersion, SetExpressCheckoutRequestDetails = reqDetails } }; SetExpressCheckoutResponseType paypalResp = BuildPayPalWebservice().SetExpressCheckout(req); if (paypalResp.Errors != null && paypalResp.Errors.Length > 0) { response.IsSuccess = false; response.Message = paypalResp.Errors[0].LongMessage; return response; } response.RedirectUrl = string.Format("{0}?cmd=_express-checkout&useraction=commit&token={1}", response.RedirectUrl, paypalResp.Token); response.RedirectRequested = true; } catch (Exception ex) { response.Message = ex.ToString(); response.IsSuccess = false; } return response; }
public IUnprocessedPayment CreateUnprocessedPayment(IPaymentRequest paymentRequest) { if (paymentRequest == null) { throw new ArgumentNullException(nameof(paymentRequest)); } if (paymentRequest.User == null) { throw new ArgumentException($"User property of {nameof(paymentRequest)} cannot be null"); } return(new UnprocessedPayment { Id = Guid.NewGuid().ToString(), CardNumber = paymentRequest.CardNumber, CardExpiryMonth = paymentRequest.CardExpiryMonth, CardExpiryYear = paymentRequest.CardExpiryYear, CardCvv = paymentRequest.CardCvv, Amount = paymentRequest.Amount, Currency = paymentRequest.Currency, UserId = paymentRequest.User.Id, User = paymentRequest.User, CreatedAt = DateTime.UtcNow }); }
/// <summary> /// Returns the HTML that should be send to the customer that wants to start a payment. /// </summary> /// <param name="request">The payment request.</param> /// <returns>The HTML that should be send to the customer that wants to start a payment.</returns> public string GetPaymentHtml(IPaymentRequest request) { using (HttpClient client = new HttpClient()) { return(GetPaymentHtml(client, request)); } }
public async Task <ProcessPaymentResult> ProcessAsync(IPaymentRequest paymentRequest) { var unprocessedPayment = _paymentsService.CreateUnprocessedPayment(paymentRequest); var acquiringBankRequest = await _acquiringBank.CreateRequestAsync(paymentRequest); _logger.LogInformation("Begun processing payment {PaymentId}.", unprocessedPayment.Id); IAcquiringBankResponse acquiringBankResponse = null; try { acquiringBankResponse = await _acquiringBank.ProcessPaymentAsync(acquiringBankRequest); _logger.LogInformation("The acquiring bank has processed the payment {PaymentId} without error.", unprocessedPayment.Id); } catch (Exception exception) { _logger.LogError( "Exception occured whilst the acquiring bank was processing payment {PaymentId}. {Exception}", unprocessedPayment.Id, exception); } var processedPayment = _paymentsService.CreateProcessedPayment(unprocessedPayment, acquiringBankResponse); var payment = CreatePayment(processedPayment); await _paymentsRepository.SavePaymentAsync(payment); _logger.LogInformation("Payment {PaymentId} has successfully been processed.", processedPayment.Id); return(new ProcessPaymentResult { Payment = processedPayment }); }
private async Task <RefundResult> PrepareRefundResult(IPaymentRequest paymentRequest, TransferResult transferResult, DateTime refundDueDate) { var assetIds = transferResult.Transactions.Unique(x => x.AssetId).ToList(); if (assetIds.MoreThanOne()) { await _log.WriteWarningAsync(nameof(PaymentRequestService), nameof(PrepareRefundResult), new { PaymentResuest = paymentRequest, RefundTransferResult = transferResult }.ToJson(), "Multiple assets are not expected"); } return(new RefundResult { Amount = transferResult.Transactions .Where(x => string.IsNullOrEmpty(x.Error)) .Sum(x => x.Amount), AssetId = assetIds.Single(), PaymentRequestId = paymentRequest.Id, PaymentRequestWalletAddress = paymentRequest.WalletAddress, Transactions = transferResult.Transactions.Select(x => new RefundTransactionResult { Amount = x.Amount, AssetId = x.AssetId, Blockchain = transferResult.Blockchain, Hash = x.Hash, SourceAddress = string.Join(";", x.Sources), DestinationAddress = string.Join(";", x.Destinations) }), DueDate = refundDueDate, Timestamp = transferResult.Timestamp }); }
public async Task <PaymentRequestStatusInfo> GetStatus(string walletAddress) { IPaymentRequest paymentRequest = await _paymentRequestRepository.FindAsync(walletAddress); if (paymentRequest == null) { throw new PaymentRequestNotFoundException(walletAddress); } IReadOnlyList <IPaymentRequestTransaction> txs = await _transactionsService.GetByWalletAsync(paymentRequest.WalletAddress); PaymentRequestStatusInfo paymentStatusInfo; if (txs.Any(x => x.IsSettlement())) { paymentStatusInfo = await GetStatusForSettlement(paymentRequest); } else if (txs.Any(x => x.IsRefund())) { paymentStatusInfo = await GetStatusForRefund(paymentRequest); } else if (txs.Any(x => x.IsPayment())) { paymentStatusInfo = await GetStatusForPayment(paymentRequest); } else { throw new Exception("Inconsistent paymentRequest status"); } return(paymentStatusInfo); }
public static PartnerPaymentEntity Create(IPaymentRequest request) { var now = DateTime.UtcNow; return(new PartnerPaymentEntity { CustomerId = request.CustomerId, //We shouldn't have a case where values are not populated when trying to save the entity FiatAmount = request.FiatAmount.Value, TokensAmount = request.TokensAmount.Value, PartnerId = request.PartnerId, Currency = request.Currency, LocationId = request.LocationId, PartnerMessageId = request.PartnerMessageId, TotalBillAmount = request.TotalBillAmount, PaymentRequestId = request.PaymentRequestId, TokensAmountPaidByCustomer = null, FiatAmountPaidByCustomer = null, Status = PaymentRequestStatus.Created, TokensReserveTimestamp = null, TokensBurnTimestamp = null, Timestamp = now, LastUpdatedTimestamp = now, PosId = request.PosId, TokensToFiatConversionRate = request.TokensToFiatConversionRate, CustomerActionExpirationTimestamp = request.CustomerActionExpirationTimestamp }); }
public async Task <IPaymentRequest> CheckoutAsync(string merchantId, string paymentRequestId, bool force) { IPaymentRequest paymentRequest = await _paymentRequestRepository.GetAsync(merchantId, paymentRequestId); if (paymentRequest == null) { throw new PaymentRequestNotFoundException(merchantId, paymentRequestId); } // Don't create new order if payment reqest status not new. if (paymentRequest.Status != PaymentRequestStatus.New) { return(paymentRequest); } await _walletsManager.EnsureBcnAddressAllocated(paymentRequest.MerchantId, paymentRequest.WalletAddress, paymentRequest.PaymentAssetId); IOrder order = await _orderService.GetLatestOrCreateAsync(paymentRequest, force); if (paymentRequest.OrderId != order.Id) { paymentRequest.OrderId = order.Id; await _paymentRequestRepository.UpdateAsync(paymentRequest); await _log.WriteInfoAsync(nameof(PaymentRequestService), nameof(CheckoutAsync), paymentRequest.ToJson(), "Payment request order updated."); } return(paymentRequest); }
public async Task UpdateStatusAsync(string walletAddress, PaymentRequestStatusInfo statusInfo = null) { IPaymentRequest paymentRequest = await _paymentRequestRepository.FindAsync(walletAddress); if (paymentRequest == null) { throw new PaymentRequestNotFoundException(walletAddress); } PaymentRequestStatusInfo newStatusInfo = statusInfo ?? await _paymentRequestStatusResolver.GetStatus(walletAddress); paymentRequest.Status = newStatusInfo.Status; paymentRequest.PaidDate = newStatusInfo.Date; paymentRequest.PaidAmount = newStatusInfo.Amount; paymentRequest.ProcessingError = paymentRequest.Status == PaymentRequestStatus.Error ? newStatusInfo.ProcessingError : PaymentRequestProcessingError.None; await _paymentRequestRepository.UpdateAsync(paymentRequest); //todo: move to separate builder service PaymentRequestRefund refundInfo = await GetRefundInfoAsync(paymentRequest.WalletAddress); await _paymentRequestPublisher.PublishAsync(paymentRequest, refundInfo); }
public MakePaymentResult MakePayment(IPaymentRequest request) { IAccount account = DataStore.GetAccount(request.DebtorAccountNumber); // Assume will be unsuccessful var result = new MakePaymentResult() { Success = false }; // Conditions for success if (account != null && account.Status == AccountStatus.Live && account.Balance >= request.Amount && account.AllowedPaymentSchemes.Contains(request.PaymentScheme)) { result.Success = true; } if (result.Success) { account.Balance -= request.Amount; DataStore.UpdateAccount(account); } return(result); }
public async Task <IPaymentRequestTransaction> CreateTransactionAsync(ICreateTransactionCommand request) { IPaymentRequest paymentRequest = null; if (!string.IsNullOrEmpty(request.WalletAddress)) { paymentRequest = await _paymentRequestRepository.FindAsync(request.WalletAddress); if (paymentRequest == null) { throw new PaymentRequestNotFoundException(request.WalletAddress); } IPaymentRequestTransaction existing = await _transactionRepository.GetByIdAsync(request.Blockchain, request.IdentityType, request.Identity, request.WalletAddress); if (existing != null) { await UpdateAsync(Mapper.Map <UpdateTransactionCommand>(request)); return(await _transactionRepository.GetByIdAsync(request.Blockchain, request.IdentityType, request.Identity, request.WalletAddress)); } } var transactionEntity = Mapper.Map <PaymentRequestTransaction>(request, opts => opts.Items["PaymentRequest"] = paymentRequest); return(await _transactionRepository.AddAsync(transactionEntity)); }
private RefundResult PrepareRefundResult(IPaymentRequest paymentRequest, TransferResult transferResult, DateTime refundDueDate) { var assetIds = transferResult.Transactions.Unique(x => x.AssetId).ToList(); if (assetIds.MoreThanOne()) { _log.Warning("Multiple assets are not expected", context: new { PaymentResuest = paymentRequest, RefundTransferResult = transferResult }); } return(new RefundResult { Amount = transferResult.GetSuccedeedTxs().Sum(x => x.Amount), AssetId = assetIds.Single(), PaymentRequestId = paymentRequest.Id, PaymentRequestWalletAddress = paymentRequest.WalletAddress, Transactions = transferResult.Transactions.Select(x => new RefundTransactionResult { Amount = x.Amount, AssetId = x.AssetId, Blockchain = transferResult.Blockchain, Hash = x.Hash, SourceAddress = string.Join(";", x.Sources), DestinationAddress = string.Join(";", x.Destinations) }), DueDate = refundDueDate, Timestamp = transferResult.Timestamp }); }
public void Validate(IPaymentRequest paymentRequest) { if (!Regex.IsMatch(paymentRequest.CardNumber, @"^\d+$")) { throw new ValidationException("Invalid Card Number"); } }
/// <summary> /// Returns the HTML that should be send to the customer that wants to start a payment. /// </summary> /// <param name="request">The payment request.</param> /// <returns>The HTML that should be send to the customer that wants to start a payment.</returns> public async Task <string> GetPaymentHtml(IPaymentRequest request) { using (HttpClient client = new HttpClient()) { return(await GetPaymentHtml(client, request)); } }
private async Task <IPaymentRequest> TryCheckoutAsync(IPaymentRequest paymentRequest, bool force) { bool locked = await _checkoutLocksService.TryAcquireLockAsync( paymentRequest.Id, paymentRequest.MerchantId, paymentRequest.DueDate); if (!locked) { throw new DistributedLockAcquireException(paymentRequest.Id); } try { await _walletsManager.EnsureBcnAddressAllocated(paymentRequest.MerchantId, paymentRequest.WalletAddress, paymentRequest.PaymentAssetId); IOrder order = await _orderService.GetLatestOrCreateAsync(paymentRequest, force); if (paymentRequest.OrderId != order.Id) { paymentRequest.OrderId = order.Id; await _paymentRequestRepository.UpdateAsync(paymentRequest); } } finally { await _checkoutLocksService.ReleaseLockAsync(paymentRequest.Id, paymentRequest.MerchantId); } return(paymentRequest); }
/// <summary> /// Create a payment request /// </summary> /// <param name="request"></param> /// <returns>Returns the id of th created payment</returns> public string Create(IPaymentRequest request) { _logger?.LogTrace("Writing request to in-memory store"); if (request == null) { throw new ArgumentNullException(nameof(request)); } if (string.IsNullOrEmpty(request.Id)) { throw new ArgumentException("The request must have an Id", nameof(request.Id)); } // Check if repository contains key if (_inMemoryStore.ContainsKey(request.Id)) { throw new Exception($"Payment request with id '{request.Id}' already exists in repository"); } var repositoryRequest = new SecuredPaymentRequest(request); var result = _inMemoryStore.GetOrAdd(request.Id, repositoryRequest); // TODO: Create exception type for this exception // TODO: Add check to verify if operation was get or add, i.e. compare request and result to ensure // they are the same _logger?.LogTrace("Writen request to in-memory store"); return(result.Id); }
public async Task <ActionResult> Post(IPaymentRequest payment) { if (!ModelState.IsValid) { return(BadRequest()); } return(Ok(await _acquiringBank.SubmitPayment(payment))); }
public static string Create(IKassaConfiguration configuration, IPaymentRequest request) { Debug.Assert(configuration != null); Debug.Assert(request != null); DataString dataString = new DataString(configuration, request); return(dataString.Create()); }
public static PaymentRequestStatusInfo GetCurrentStatusInfo(this IPaymentRequest src) { return(new PaymentRequestStatusInfo { Amount = src.Amount, Date = src.PaidDate, Status = src.Status, ProcessingError = src.ProcessingError }); }
public async Task PublishAsync(IPaymentRequest paymentRequest, Core.Domain.PaymentRequests.PaymentRequestRefund refundInfo) { PaymentRequestDetailsMessage message = await _paymentRequestDetailsBuilder.Build < PaymentRequestDetailsMessage, PaymentRequestOrder, PaymentRequestTransaction, PaymentRequestRefund>(paymentRequest, refundInfo); await PublishAsync(message); }
private async Task UpdateStatusAsync(IPaymentRequest paymentRequest, PaymentRequestStatusInfo statusInfo = null) { PaymentRequestStatusInfo newStatusInfo = statusInfo ?? await _paymentRequestStatusResolver.GetStatus(paymentRequest.WalletAddress); PaymentRequestStatus previousStatus = paymentRequest.Status; PaymentRequestProcessingError previousProcessingError = paymentRequest.ProcessingError; paymentRequest.Status = newStatusInfo.Status; paymentRequest.PaidDate = newStatusInfo.Date; if (newStatusInfo.Amount.HasValue) { paymentRequest.PaidAmount = newStatusInfo.Amount.Value; } paymentRequest.ProcessingError = (paymentRequest.Status == PaymentRequestStatus.Error || paymentRequest.Status == PaymentRequestStatus.SettlementError) ? newStatusInfo.ProcessingError : PaymentRequestProcessingError.None; await _paymentRequestRepository.UpdateAsync(paymentRequest); // if we are updating status from "InProcess" to any other - we have to release the lock if (previousStatus == PaymentRequestStatus.InProcess) { await _paymentLocksService.ReleaseLockAsync(paymentRequest.Id, paymentRequest.MerchantId); } PaymentRequestRefund refundInfo = await GetRefundInfoAsync(paymentRequest.WalletAddress); if (paymentRequest.Status != previousStatus || (paymentRequest.Status == PaymentRequestStatus.Error && paymentRequest.ProcessingError != previousProcessingError)) { await _paymentRequestPublisher.PublishAsync(paymentRequest, refundInfo); IAssetGeneralSettings assetSettings = await _assetSettingsService.GetGeneralAsync(paymentRequest.PaymentAssetId); // doing auto settlement only once // Some flows assume we can get updates from blockchain multiple times for the same transaction // which leads to the same payment request status if (paymentRequest.StatusValidForSettlement() && (assetSettings?.AutoSettle ?? false)) { if (paymentRequest.Status != PaymentRequestStatus.Confirmed && !_autoSettleSettingsResolver.AllowToMakePartialAutoSettle(paymentRequest.PaymentAssetId)) { return; } await SettleAsync(paymentRequest.MerchantId, paymentRequest.Id); } } }
public async Task AddAsync(IPaymentRequest paymentRequest) { using (var context = _contextFactory.CreateDataContext()) { var entity = PartnerPaymentEntity.Create(paymentRequest); context.PartnersPayments.Add(entity); await context.SaveChangesAsync(); } }
public async Task UpdateAsync(IPaymentRequest paymentRequest) { var entity = _mapper.Map <PaymentRequestEntity>(paymentRequest); using (var context = _contextFactory.CreateDataContext()) { context.PaymentRequests.Update(entity); await context.SaveChangesAsync(); } }
public static int AmountAsNumber(this IPaymentRequest self) { if (self.CurrencyCode == CurrencyCode.JapaneseYen) { return((int)self.Amount); } else { return((int)(self.Amount * 100)); } }
public async Task UpdateStatusAsync(string walletAddress, PaymentRequestStatusInfo statusInfo = null) { IPaymentRequest paymentRequest = await _paymentRequestRepository.FindAsync(walletAddress); if (paymentRequest == null) { throw new PaymentRequestNotFoundException(walletAddress); } await UpdateStatusAsync(paymentRequest, statusInfo); }
public async Task UpdateStatusAsync(string merchanttId, string paymentRequestId, PaymentRequestStatusInfo statusInfo = null) { IPaymentRequest paymentRequest = await _paymentRequestRepository.GetAsync(merchanttId, paymentRequestId); if (paymentRequest == null) { throw new PaymentRequestNotFoundException(merchanttId, paymentRequestId); } await UpdateStatusAsync(paymentRequest, statusInfo); }
public IPaymentResponse ProcessPayment(IPaymentRequest request) { if (string.IsNullOrEmpty(request.Token)) { this._logger.Info("Begin Express Checkout"); return BeginExpressCheckout(request); } else { this._logger.Info("End Express Checkout"); return EndExpressCheckout(request); } }
private void createPaymentRequest(IPaymentRequest pr) { resetPaymentRequest(); bool validationResult = pr.Validate(); PaymentRequestCreationLogControl.IsValid = validationResult; if (validationResult) { if (pr is EPaymentMessage) { PaymentRequestCreationLogControl.UncryptedSignature = ((EPaymentMessage)pr).SignatureBase; } pr.SignMessage(tbSharedSecret.Text); if (pr is EPaymentMessage) { PaymentRequestCreationLogControl.CryptedSignature = ((EPaymentMessage)pr).Signature; } if (pr is IHttpRedirectPaymentRequest) { displayPaymentRequestLink(((IHttpRedirectPaymentRequest)pr).PaymentRequestUrl); } else { hlPaymentRequest.NavigateUrl = null; hlPaymentRequest.Visible = false; } if (pr is IHttpPostPaymentRequest) { postPaymentRequestToRender = (IHttpPostPaymentRequest)pr; } } }
private IPaymentResponse EndExpressCheckout(IPaymentRequest request) { PaymentResponse response = new PaymentResponse (); GetExpressCheckoutDetailsReq req = new GetExpressCheckoutDetailsReq() { GetExpressCheckoutDetailsRequest = new GetExpressCheckoutDetailsRequestType() { Version = this._paymentGateway.APIVersion, Token = request.Token, } }; // query PayPal for transaction details GetExpressCheckoutDetailsResponseType paypalResp = BuildPayPalWebservice().GetExpressCheckoutDetails(req); //handle error if (paypalResp.Errors != null && paypalResp.Errors.Length > 0) { response.IsSuccess = false; response.Message = paypalResp.Errors[0].LongMessage; return response; } GetExpressCheckoutDetailsResponseDetailsType respDetails = paypalResp.GetExpressCheckoutDetailsResponseDetails; PaymentDetailsType[] sPaymentDetails = new PaymentDetailsType[1]; sPaymentDetails[0] = new PaymentDetailsType() { OrderTotal = new BasicAmountType() { currencyID = respDetails.PaymentDetails.FirstOrDefault().OrderTotal.currencyID, Value = respDetails.PaymentDetails.FirstOrDefault().OrderTotal.Value }, /*must specify PaymentAction and PaymentActionSpecific, or it'll fail with PaymentAction : Required parameter missing (error code: 81115)*/ PaymentAction = PaymentActionCodeType.Sale, // Recurring = RecurringFlagType.Y, PaymentActionSpecified = true }; // prepare for commiting transaction DoExpressCheckoutPaymentReq payReq = new DoExpressCheckoutPaymentReq() { DoExpressCheckoutPaymentRequest = new DoExpressCheckoutPaymentRequestType() { Version = this._paymentGateway.APIVersion, DoExpressCheckoutPaymentRequestDetails = new DoExpressCheckoutPaymentRequestDetailsType() { Token = paypalResp.GetExpressCheckoutDetailsResponseDetails.Token, /*must specify PaymentAction and PaymentActionSpecific, or it'll fail with PaymentAction : Required parameter missing (error code: 81115)*/ PaymentAction = PaymentActionCodeType.Sale, PaymentActionSpecified = true, PayerID = paypalResp.GetExpressCheckoutDetailsResponseDetails.PayerInfo.PayerID, PaymentDetails = sPaymentDetails } } }; // commit transaction and display results to user DoExpressCheckoutPaymentResponseType doResponse = BuildPayPalWebservice().DoExpressCheckoutPayment(payReq); try { //handle error if (paypalResp.Errors != null && paypalResp.Errors.Length > 0) { response.IsSuccess = false; response.Message = paypalResp.Errors[0].LongMessage; return response; } } catch (Exception ex) { } if (!string.IsNullOrEmpty(doResponse.DoExpressCheckoutPaymentResponseDetails.PaymentInfo[0].TransactionID) && doResponse.Ack == AckCodeType.Success) { response.TransactionId = doResponse.DoExpressCheckoutPaymentResponseDetails.PaymentInfo[0].TransactionID; } else { response.IsSuccess = false; response.Message = "No Transaction id returned"; return response; } // Create Recurring profile. var pp_response = CreateRecurringPaymentsProfile(paypalResp.GetExpressCheckoutDetailsResponseDetails.Token, respDetails.PaymentDetails.FirstOrDefault().OrderTotal, respDetails.PaymentDetails[0], request); string profileId = pp_response.CreateRecurringPaymentsProfileResponseDetails.ProfileID; return null; }
private CreateRecurringPaymentsProfileResponseType CreateRecurringPaymentsProfile(string token, BasicAmountType OrderTotal, PaymentDetailsType paymentDetailsType, IPaymentRequest request) { CreateRecurringPaymentsProfileReq pp_request = new CreateRecurringPaymentsProfileReq() { CreateRecurringPaymentsProfileRequest = new CreateRecurringPaymentsProfileRequestType() { Version = "64.0", CreateRecurringPaymentsProfileRequestDetails = new CreateRecurringPaymentsProfileRequestDetailsType() { Token = token, RecurringPaymentsProfileDetails = new RecurringPaymentsProfileDetailsType() { BillingStartDate = DateTime.Now.AddDays(1), //SubscriberName = registrationData.UserName }, ScheduleDetails = new ScheduleDetailsType() { Description = paymentDetailsType.OrderDescription,//"Test-Account", MaxFailedPayments = 6, MaxFailedPaymentsSpecified = true, AutoBillOutstandingAmount = AutoBillType.AddToNextBilling, AutoBillOutstandingAmountSpecified = true, PaymentPeriod = new BillingPeriodDetailsType() { Amount = new BasicAmountType() { Value = OrderTotal.Value, currencyID = CurrencyCodeType.USD }, BillingFrequency = 1, BillingPeriod = BillingPeriodType.Day, }, ActivationDetails = new ActivationDetailsType() { InitialAmount = OrderTotal, FailedInitialAmountAction = FailedPaymentActionType.ContinueOnFailure } } } } }; CreateRecurringPaymentsProfileResponseType pp_response = new CreateRecurringPaymentsProfileResponseType(); pp_response = BuildPayPalWebservice().CreateRecurringPaymentsProfile(pp_request); return pp_response; }