I know you have to create a customer and verify a bank account, but I'm not sure how to do the latter.
How do I go about verifying them on the customer?
To add a bank account to a customer, you need to create a token and add it to the sourceToken parameter since adding using the bank account services were not implement as of now. For Example:
BankAccountCreateOptions bankAccount = new BankAccountCreateOptions();
bankAccount.SourceBankAccount = new SourceBankAccount() {
AccountHolderName = accountHolderName,
AccountHolderType = "company",
AccountNumber = bankAccountNumber,
BankName = bankName,
Country = "US",
Currency = "usd",
RoutingNumber = bankAccountRoutingNumber
};
// Setup the customer
StripeCustomerCreateOptions options = new StripeCustomerCreateOptions();
options.Email = email;
options.Description = company;
options.PlanId = plan.Id;
options.TrialEnd = DateTime.UtcNow.AddMonths(1);
options.SourceToken = bankAccount.SourceToken;
// Create the customer
StripeCustomer customer = new StripeCustomerService().Create(options);
However I still don't know how to verify the bank account once created.
You can login to bank accounts by using test users in https://plaid.com/docs/api/#sandbox and register a user as stripe ACH. Create token by using test user bank details and create a customer for user.Do charges by using created customer id.
Related
I am working on a C# application where the app users will purchase a subscription for their clients. Since they will buy multiple subscriptions, I need to add a description (client name) to a product so it shows up in the billing portal along with the price. My current checkout code works fine and the relevant part is here:
var options = new Stripe.Checkout.SessionCreateOptions
{
LineItems = new List<SessionLineItemOptions>
{
new SessionLineItemOptions
{
Price = priceId,
Quantity = 1
},
},
PaymentMethodTypes = new List<string>
{
"card",
},
Mode = "subscription",
SuccessUrl = string.Concat("https://", domain, "/success/", hhid, "?session_id={CHECKOUT_SESSION_ID}"),
CancelUrl = string.Concat("https://", domain),
Customer = customerId,
SubscriptionData = new SessionSubscriptionDataOptions()
{
Metadata = new Dictionary<string, string>()
{
{ "userId", userId.ToString() }
}
}
};
if (!string.IsNullOrEmpty(user.PaymentCustomerId))
options.Customer = user.PaymentCustomerId;
var service = new Stripe.Checkout.SessionService();
Stripe.Checkout.Session session = await service.CreateAsync(options);
Response.Headers.Add("Location", session.Url);
I contacted Stripe support and their response was
In this particular case we do not have an option that allow you to add a description, but you are able to add the name with price_data parameter into the Checkout, Invoice Items, and Subscription Schedule APIs.
https://stripe.com/docs/api/subscription_items/create
https://stripe.com/docs/billing/prices-guide
They provided links to the two articles which I have read and re-read and don't understand how to implement it. If anyone can help it would be greatly appreciated.
Unfortunately, the Billing Portal does not show a description for the Product.
If you want to use the Billing Portal, then you would need to specify the client name in the name for the Product e.g. [client name] Product #1, and this would require you to create a new Product and Price for every client.
You can do it in the Checkout Session creation :
https://stripe.com/docs/api/checkout/sessions/create#create_checkout_session-line_items-price_data-product_data-name
https://stripe.com/docs/api/checkout/sessions/create#create_checkout_session-line_items-price_data
Or, create the Product and Price separately :
https://stripe.com/docs/api/products/create
https://stripe.com/docs/api/prices/create
Anyone who is familliar with the Mollie API?
I am trying to set up a payment for a webshop, but I don't have much knowledge of the Mollie API.
So I got 2 questions:
The Order API of Mollie is like the Payment API, but the order API is a bit more "advanced" and more made for a webshop with products? Is that correct?
I got the following code, I assume (according to the Mollie documentation of how a payment works)
that I can set up a payment (order) with an amount and other additional information, the user will than be redirected to the Mollie platform where he can choose a payment method.
List<OrderLineRequest> OrderLineList = new List<OrderLineRequest>();
foreach(product in cart) {
OrderLineRequest Orderline = new OrderLineRequest();
Orderline.Name = B.GetProductName(ProductID);
Orderline.Quantity = Amount;
Orderline.UnitPrice = new Amount(Currency.EUR, ProductPrice.ToString());
Orderline.TotalAmount = new Amount(Currency.EUR, (Amount * ProductPrice).ToString());
Orderline.VatRate = "21.00";
Orderline.VatAmount = new Amount(Currency.EUR, ((Amount * ProductPrice)*0,21).ToString());
OrderLineList.Add(Orderline);
}
IOrderClient orderClient = new OrderClient("my API key");
OrderRequest orderRequest = new OrderRequest()
{
Amount = new Amount(Currency.EUR, "Amount needs to be paid"),
OrderNumber = OrderID.ToString(),
Lines = OrderLineList,
BillingAddress = new OrderAddressDetails()
{
GivenName = FirstName,
FamilyName = LastName,
Email = Email,
City = City,
Country = Country,
PostalCode = PostalCode,
StreetAndNumber = Street + " " + HouseNumber
},
RedirectUrl = "URL I want to redirect to when payment is done",
Locale = Locale.en_US
};
What else do I have to do for the user to be redirected to the Mollie platform to pay?
Thanks alot for taking time to read this, I hope you can help me out!
Thanks in advance!
I'm writing a service which allows users to sign up for classes, at the time of sign up the class instructor may not be known, but I need to create a pending charge to assure that the instructor will be paid. Later I want to update the pending and set a finalization date, e.g update the instructors account Id and 24 hours after the class ends pay the instructor
I'm trying to understand the work flow of how to do it, but the API Doc's don't seem to be helpful.
I have a service to create Payment Intents like so:
var paymentIntentService = new PaymentIntentService();
var paymentIntentTransferDataOptions = new PaymentIntentTransferDataOptions();
var options = new PaymentIntentCreateOptions
{
Amount = paymentIntentTransactionOptions.AmountInCents,
Currency = DEFAULT_TRANSACTION_CURRENCY,
ApplicationFeeAmount = this.CalculateApplicationFee(paymentIntentTransactionOptions),
ReceiptEmail = "", // TODO Obtain this from the Logged in user
PaymentMethodTypes = new List<string> { "card" },
};
var requestOptions = new RequestOptions();
requestOptions.IdempotencyKey = INTENT_IDEM_PREFIX + paymentIntentTransactionOptions.TransactionId;
var paymentIntent = await paymentIntentService.CreateAsync(options, requestOptions);
I would like to create a pending charge with no destination at first and before completion I will update the user to send it to.
The update process I would assume to just, call Get on the PaymentIntent and Update the Sender.
My confusion lays around 3 areas.
How does the API Know what user I'm allowed to send on behalf of a user?
e.g I just provide an accountId. Does the api have full control of other accounts after registration?
How can I Create a pending charge, to assure the instructor gets paid, does that happen when I create the payment intent?
How do I finalize the transaction (Now, or preferable with a future date)
I recently created an entire sharing economy platform with Stripe Connect, so I'm fairly familiar with it.
Charging the User: You'll need to create a regular charge for the user after they schedule the class. Read this on creating charges. This will charge the user $X and hold it in the platforms account without yet transferring it.
Paying the Instructor: You'll need to create a separate transfer using source_transaction to send the money to the instructor's account. source_transaction will basically just make the transfer from the charge you made earlier from the customer. You can read more about that here.
Regarding holding the funds for 24hrs, if you use source_transaction, the money won't become available for payout until after 2 days due to processing. You can read more about that here. If you want it to become available faster, you have 2 options. Either you can enable Instant Payout (which I don't recommend) or you can have a reserve balance in your platform stripe balance to cover the one-day layover and then you can make the transfers without source_transaction.
Okay, so after asking a few more questions and reading api docs. There are a few ways of doing this. #nachshonf answer will get the job done. However if I use transfers and seperate charges, The platform will be responsible for the Stripe fees and refund.
Instead I've come up with a more complex way of doing this, but will assure less of a headache for me in the long run. Basically I create a hold via the platform, and then when the instructor is resolved will request to issue another charge for the instructor. This way all disputes go through the instructor.
First off I'll create a hold via the platform, This is pretty simple
public Task<PaymentIntent>CreatePlatformHoldAsync(long amountInCents, string customerId,
string paymentMethodId, string idem = null, string currency = DEFAULT_TRANSACTION_CURRENCY)
{
var paymentIntentService = new PaymentIntentService();
var options = new PaymentIntentCreateOptions
{
Amount = amountInCents,
Currency = currency,
//ReceiptEmail = "", // TODO Obtain this from the Logged in user
PaymentMethodTypes = new List<string> { "card" },
CustomerId = customerId,
PaymentMethodId = paymentMethodId,
CaptureMethod = "manual",
};
var requestOptions = new RequestOptions { IdempotencyKey = idem };
return paymentIntentService.CreateAsync(options, requestOptions);
}
/// <summary>
/// Confirm a payment intent, on the platform or sellerAccount
/// </summary>
/// <param name="sellerStripeAccountId">optional, omit for the platform confirm</param>
public Task<PaymentIntent> ConfirmPaymentAsync(string paymentIntentId,
string sellerStripeAccountId = null)
{
var paymentIntentService = new PaymentIntentService();
var paymentIntentConfirmOptions = new PaymentIntentConfirmOptions();
var options = new RequestOptions
{
StripeAccount = sellerStripeAccountId
};
return paymentIntentService.ConfirmAsync(paymentIntentId,
paymentIntentConfirmOptions, options);
}
First create a hold, Then confirm it to authorize the charges. Then I'll create another charge for the instructor
public Task<PaymentIntent> CreateDestinationChargeAsync(long amountInCents, long applicationFeeInCents,
string paymentMethodId, string destinationAccountId, string idem = null,
string currency = DEFAULT_TRANSACTION_CURRENCY)
{
var paymentIntentService = new PaymentIntentService();
var options = new PaymentIntentCreateOptions
{
Amount = amountInCents,
Currency = currency,
ApplicationFeeAmount = applicationFeeInCents,
//ReceiptEmail = "", // TODO Obtain this from the Logged in user
PaymentMethodTypes = new List<string> { "card" },
PaymentMethodId = paymentMethodId,
};
var requestOptions = new RequestOptions
{
IdempotencyKey = idem,
StripeAccount = destinationAccountId
};
return paymentIntentService.CreateAsync(options, requestOptions);
}
After this is paid you can cancel the platform hold or wait 7 days for the hold to age away.
Edit For Usages
public async Task<Customer> CreateCustomerAsync(string email, string sourceToken)
{
var options = new CustomerCreateOptions
{
Email = email, // "paying.user#example.com",
Source = sourceToken,
};
var service = new CustomerService();
return await service.CreateAsync(options);
}
/// <summary>
/// Creates a payment method for a customer on the sellers stripe account
/// </summary>
/// <returns></returns>
public async Task<PaymentMethod> CreatePaymentMethodAsync(string customerId, string paymentMethodId,
string stripeConnectAccountId)
{
var paymentMethodService = new PaymentMethodService();
var paymentMethodOptions = new PaymentMethodCreateOptions
{
CustomerId = customerId,
PaymentMethodId = paymentMethodId
};
var requestOptions = new RequestOptions()
{
StripeAccount = stripeConnectAccountId
};
return await paymentMethodService.CreateAsync(paymentMethodOptions, requestOptions);
}
Usage:
//set destination here
var destinationAccountId = "";
var configuration = this.GetConfiguration();
StripeConfiguration.ApiKey = configuration["Stripe:ClientSecret"];
//This is the name of the service which I define the methods above
var stripeService = new StripeConnectService(configuration);
//"tok_mastercard" is a test value to represent a paymentToken
var customer = await stripeService.CreateCustomerAsync("CustomerEmail#gmail.com", "tok_mastercard");
var sharedPaymentMethod = await stripeService.CreatePaymentMethodAsync(customer.Id,
customer.DefaultSourceId, destinationAccount.AccountId);
var paymentIntent = await stripeService.CreateDestinationChargeAsync(1000, 100,
sharedPaymentMethod.Id, destinationAccountId);
await stripeService.ConfirmPaymentAsync(paymentIntent.Id, destinationAccountId);
These are examples and are not meant for production I'm only using them to test the flow.
Note: the payment token represents a customer. I haven't implemented a way to obtain the payment token but it looks like you will need stripe.js so they can enter there card information to create a token.
I am using the .NET PayPal SDK (github.com/paypal/PayPal-NET-SDK) and am able to successfully create a paypal request, redirect the user, the user completes payment and all is well.
For the life of me, I can't figure out how to show the "Credit Card / No Paypal Account" screen instead of the "Login with paypal ... or click here if you don't have paypal to pay with credit card" screen.
Most of my users don't have paypal and just want to pay with a credit card (and I'd like to process it all through paypal, directly through their site so that users never give me their credit card number).
Here is the code I have that work for paying with paypal, but how can I tell it to show the "credit card/guest checkout" on paypal's landing page?
string PaypalRedirectURL(string returnURL, string cancelURL)
{
// create the transaction list
var trans = new List<Transaction>();
// make the actual transaction
var t = new Transaction()
{
description = "Payment For Something",
invoice_number = "inv1234",
amount = new Amount()
{
currency = "USD",
total = "2.00",
details = new Details
{
tax = "0",
shipping = "0",
subtotal = "2.00"
}
}
};
t.item_list = new ItemList();
t.item_list.items = new List<Item>();
Item i = new Item();
i.name = "Something I charge for";
i.quantity = "1";
i.sku = "item0001";
i.currency = "USD";
i.price = "2.00";
// Add item to item list
t.item_list.items.Add(i);
//add transaction to transaction list
trans.Add(t);
// create the payment
var payment = Payment.Create(GetAPIContext(), new Payment
{
intent = "sale",
payer = new Payer
{
payment_method = "paypal"
},
transactions = trans,
redirect_urls = new RedirectUrls
{
return_url = returnURL,
cancel_url = cancelURL
}
});
var links = payment.links.GetEnumerator();
string paypalRedirectUrl = null;
while (links.MoveNext())
{
Links lnk = links.Current;
// get the payment redirect link
if (lnk.rel.ToLower().Trim().Equals("approval_url"))
{
//saving the payapalredirect URL to which user will be redirected for payment
paypalRedirectUrl = lnk.href;
}
}
return paypalRedirectUrl;
}
I've tried numerous variations of [payment_method = "paypal"] (like (="credit_card", etc) but nothing seems to work. Again, I don't want to provide the credit card to this, I want the credit card "guest checkout" on paypal's site to show by default.
This is the screen the user gets on paypal (they can click the "pay with credit card" but I want to know if I can send them directly to the credit card screen without them having to click anything.
Current Page they are sent to:
Default paypal screen
Page I'd like the user to see by default (with the credit card fields displayed):
Desired default paypal page
Any help would be greatly appreciated .. thanks in advance
I have ran out of ideas and none of the answers for the similar question was helpful, hence I am desperate now. I am trying to integrate paypal payment into my app. I have set negative testing to off in my sandbox account. I am using visual studio 2013, here is my example code:
Address billingAddress = new Address();
billingAddress.line1 = "52 N Main ST";
billingAddress.city = "Johnstown";
billingAddress.country_code = "US";
billingAddress.postal_code = "43210";
billingAddress.state = "OH";
CreditCard creditCard = new CreditCard();
creditCard.number = "4417119669820331";
creditCard.type = "visa";
creditCard.expire_month = 11;
creditCard.expire_year = 2018;
creditCard.cvv2 = "874";
creditCard.first_name = "Joe";
creditCard.last_name = "Shopper";
creditCard.billing_address = billingAddress;
var amountDetails = new Details();
amountDetails.subtotal = "7.41";
amountDetails.tax = "0.03";
amountDetails.shipping = "0.03";
Amount amount = new Amount();
amount.total = "7.47";
amount.currency = "USD";
amount.details = amountDetails;
Transaction transaction = new Transaction();
transaction.amount = amount;
transaction.description = "This is the payment transaction description.";
List<Transaction> transactions = new List<Transaction>();
transactions.Add(transaction);
FundingInstrument fundingInstrument = new FundingInstrument();
fundingInstrument.credit_card = creditCard;
List<FundingInstrument> fundingInstruments = new List<FundingInstrument>();
fundingInstruments.Add(fundingInstrument);
Payer payer = new Payer();
payer.funding_instruments = fundingInstruments;
payer.payment_method = "credit_card";
Payment payment = new Payment();
payment.intent = "sale";
payment.payer = payer;
payment.transactions = transactions;
var config = ConfigManager.Instance.GetProperties();
var accessToken = new OAuthTokenCredential(config).GetAccessToken();
try
{
var apiContext = new APIContext(accessToken);
var createdPayment = payment.Create(apiContext);
}
catch (PayPal.HttpException e)
{
return Json(e.InnerException, JsonRequestBehavior.AllowGet);
}
Now each time I am attempting to create the payment, I am getting the following:
"{\"name\":\"INTERNAL_SERVICE_ERROR\",\"message\":\"An internal service error has occurred\",\"information_link\":\"https://developer.paypal.com/webapps/developer/docs/api/#INTERNAL_SERVICE_ERROR\",\"debug_id\":\"f0d2f70ac4693\"}"
debug_id changes each time i attempt. any help would be hugely appreciated.
Try changing the credit card number you're using to a different number. This error has been happening a lot in the recent weeks on PayPal's sandbox environment and is (most of the time) related to overusing a credit card number. The best thing to try would be to create a new Sandbox test account via the Developer Dashboard and generate a new credit card number there.
The PayPal payments team is currently working on a solution on sandbox to return a more meaningful error when this happens.
EDIT:
As an alternative to creating a new Sandbox test account to get a new credit card number for testing, you can also try the credit card number generator available in the following FAQ on the PayPal Technical Support site:
Sandbox - Generate an Additional Credit Card Number for a Sandbox account.
Scroll down to Step 4 on that page to find the generator.