public async Task <bool> CreditAccountAsync(ISubscriber subscriber, decimal creditAmount) { var customerService = new CustomerService(); Customer customer = null; var customerExists = subscriber.Gateway == GatewayType.Stripe && !string.IsNullOrWhiteSpace(subscriber.GatewayCustomerId); if (customerExists) { customer = await customerService.GetAsync(subscriber.GatewayCustomerId); } else { customer = await customerService.CreateAsync(new CustomerCreateOptions { Email = subscriber.BillingEmailAddress(), Description = subscriber.BillingName(), }); subscriber.Gateway = GatewayType.Stripe; subscriber.GatewayCustomerId = customer.Id; } await customerService.UpdateAsync(customer.Id, new CustomerUpdateOptions { AccountBalance = customer.AccountBalance - (long)(creditAmount * 100) }); return(!customerExists); }
public async Task<bool> UpdatePaymentMethodAsync(ISubscriber subscriber, string paymentToken) { if(subscriber == null) { throw new ArgumentNullException(nameof(subscriber)); } if(subscriber.Gateway.HasValue && subscriber.Gateway.Value != Enums.GatewayType.Braintree) { throw new GatewayException("Switching from one payment type to another is not supported. " + "Contact us for assistance."); } var updatedSubscriber = false; Customer customer = null; if(!string.IsNullOrWhiteSpace(subscriber.GatewayCustomerId)) { customer = await _gateway.Customer.FindAsync(subscriber.GatewayCustomerId); } if(customer == null) { var result = await _gateway.Customer.CreateAsync(new CustomerRequest { Email = subscriber.BillingEmailAddress(), PaymentMethodNonce = paymentToken }); if(!result.IsSuccess()) { throw new GatewayException("Cannot create customer."); } customer = result.Target; subscriber.Gateway = Enums.GatewayType.Braintree; subscriber.GatewayCustomerId = customer.Id; updatedSubscriber = true; } else { if(customer.DefaultPaymentMethod != null) { var deleteResult = await _gateway.PaymentMethod.DeleteAsync(customer.DefaultPaymentMethod.Token); if(!deleteResult.IsSuccess()) { throw new GatewayException("Cannot delete old payment method."); } } var result = await _gateway.PaymentMethod.CreateAsync(new PaymentMethodRequest { PaymentMethodNonce = paymentToken, CustomerId = customer.Id }); if(!result.IsSuccess()) { throw new GatewayException("Cannot add new payment method."); } } return updatedSubscriber; }
public async Task <bool> UpdatePaymentMethodAsync(ISubscriber subscriber, string paymentToken) { if (subscriber == null) { throw new ArgumentNullException(nameof(subscriber)); } if (subscriber.Gateway.HasValue && subscriber.Gateway.Value != Enums.GatewayType.Stripe) { throw new GatewayException("Switching from one payment type to another is not supported. " + "Contact us for assistance."); } var updatedSubscriber = false; var cardService = new StripeCardService(); var bankSerice = new BankAccountService(); var customerService = new StripeCustomerService(); StripeCustomer customer = null; if (!string.IsNullOrWhiteSpace(subscriber.GatewayCustomerId)) { customer = await customerService.GetAsync(subscriber.GatewayCustomerId); } if (customer == null) { customer = await customerService.CreateAsync(new StripeCustomerCreateOptions { Description = subscriber.BillingName(), Email = subscriber.BillingEmailAddress(), SourceToken = paymentToken }); subscriber.Gateway = Enums.GatewayType.Stripe; subscriber.GatewayCustomerId = customer.Id; updatedSubscriber = true; } else { if (paymentToken.StartsWith("btok_")) { await bankSerice.CreateAsync(customer.Id, new BankAccountCreateOptions { SourceToken = paymentToken }); } else { await cardService.CreateAsync(customer.Id, new StripeCardCreateOptions { SourceToken = paymentToken }); } if (!string.IsNullOrWhiteSpace(customer.DefaultSourceId)) { var source = customer.Sources.FirstOrDefault(s => s.Id == customer.DefaultSourceId); if (source.BankAccount != null) { await bankSerice.DeleteAsync(customer.Id, customer.DefaultSourceId); } else if (source.Card != null) { await cardService.DeleteAsync(customer.Id, customer.DefaultSourceId); } } } return(updatedSubscriber); }
public async Task <bool> UpdatePaymentMethodAsync(ISubscriber subscriber, PaymentMethodType paymentMethodType, string paymentToken) { if (subscriber == null) { throw new ArgumentNullException(nameof(subscriber)); } if (subscriber.Gateway.HasValue && subscriber.Gateway.Value != GatewayType.Stripe) { throw new GatewayException("Switching from one payment type to another is not supported. " + "Contact us for assistance."); } var createdCustomer = false; Braintree.Customer braintreeCustomer = null; string stipeCustomerSourceToken = null; var stripeCustomerMetadata = new Dictionary <string, string>(); var stripePaymentMethod = paymentMethodType == PaymentMethodType.Card || paymentMethodType == PaymentMethodType.BankAccount; var cardService = new CardService(); var bankSerice = new BankAccountService(); var customerService = new CustomerService(); Customer customer = null; if (!string.IsNullOrWhiteSpace(subscriber.GatewayCustomerId)) { customer = await customerService.GetAsync(subscriber.GatewayCustomerId); if (customer.Metadata?.Any() ?? false) { stripeCustomerMetadata = customer.Metadata; } } var hadBtCustomer = stripeCustomerMetadata.ContainsKey("btCustomerId"); if (stripePaymentMethod) { stipeCustomerSourceToken = paymentToken; } else if (paymentMethodType == PaymentMethodType.PayPal) { if (hadBtCustomer) { var pmResult = await _btGateway.PaymentMethod.CreateAsync(new Braintree.PaymentMethodRequest { CustomerId = stripeCustomerMetadata["btCustomerId"], PaymentMethodNonce = paymentToken }); if (pmResult.IsSuccess()) { var customerResult = await _btGateway.Customer.UpdateAsync( stripeCustomerMetadata["btCustomerId"], new Braintree.CustomerRequest { DefaultPaymentMethodToken = pmResult.Target.Token }); if (customerResult.IsSuccess() && customerResult.Target.PaymentMethods.Length > 0) { braintreeCustomer = customerResult.Target; } else { await _btGateway.PaymentMethod.DeleteAsync(pmResult.Target.Token); hadBtCustomer = false; } } else { hadBtCustomer = false; } } if (!hadBtCustomer) { var customerResult = await _btGateway.Customer.CreateAsync(new Braintree.CustomerRequest { PaymentMethodNonce = paymentToken, Email = subscriber.BillingEmailAddress(), Id = subscriber.BraintreeCustomerIdPrefix() + subscriber.Id.ToString("N").ToLower() + Utilities.CoreHelpers.RandomString(3, upper: false, numeric: false), CustomFields = new Dictionary <string, string> { [subscriber.BraintreeIdField()] = subscriber.Id.ToString() } }); if (!customerResult.IsSuccess() || customerResult.Target.PaymentMethods.Length == 0) { throw new GatewayException("Failed to create PayPal customer record."); } braintreeCustomer = customerResult.Target; } } else { throw new GatewayException("Payment method is not supported at this time."); } if (stripeCustomerMetadata.ContainsKey("btCustomerId")) { if (braintreeCustomer?.Id != stripeCustomerMetadata["btCustomerId"]) { var nowSec = Utilities.CoreHelpers.ToEpocSeconds(DateTime.UtcNow); stripeCustomerMetadata.Add($"btCustomerId_{nowSec}", stripeCustomerMetadata["btCustomerId"]); } stripeCustomerMetadata["btCustomerId"] = braintreeCustomer?.Id; } else if (!string.IsNullOrWhiteSpace(braintreeCustomer?.Id)) { stripeCustomerMetadata.Add("btCustomerId", braintreeCustomer.Id); } try { if (customer == null) { customer = await customerService.CreateAsync(new CustomerCreateOptions { Description = subscriber.BillingName(), Email = subscriber.BillingEmailAddress(), SourceToken = stipeCustomerSourceToken, Metadata = stripeCustomerMetadata }); subscriber.Gateway = GatewayType.Stripe; subscriber.GatewayCustomerId = customer.Id; createdCustomer = true; } if (!createdCustomer) { string defaultSourceId = null; if (stripePaymentMethod) { if (paymentToken.StartsWith("btok_")) { var bankAccount = await bankSerice.CreateAsync(customer.Id, new BankAccountCreateOptions { SourceToken = paymentToken }); defaultSourceId = bankAccount.Id; } else { var card = await cardService.CreateAsync(customer.Id, new CardCreateOptions { SourceToken = paymentToken, }); defaultSourceId = card.Id; } } foreach (var source in customer.Sources.Where(s => s.Id != defaultSourceId)) { if (source is BankAccount) { await bankSerice.DeleteAsync(customer.Id, source.Id); } else if (source is Card) { await cardService.DeleteAsync(customer.Id, source.Id); } } customer = await customerService.UpdateAsync(customer.Id, new CustomerUpdateOptions { Metadata = stripeCustomerMetadata, DefaultSource = defaultSourceId }); } } catch (Exception e) { if (braintreeCustomer != null && !hadBtCustomer) { await _btGateway.Customer.DeleteAsync(braintreeCustomer.Id); } throw e; } return(createdCustomer); }