In my angular app I want to use the stripe-API. I want to add a payment method to the customer. e.g. SEPA
My first Problem is to choose the right endpoint. I think it is the "create source"-endpoint.
My second problem is to pass the correct params. My postman body looks like
{
type: 'sepa_debit',
sepa_debit: {iban: 'DE12345678901234567890'},
currency: 'eur',
customer: 'cus_Jjg6mhSRHZuXYZ'
owner: {
name: 'Max Mustermann',
}
Response:
"error": {
"code": "parameter_unknown",
"doc_url": "https://stripe.com/docs/error-codes/parameter-unknown",
"message": "Received unknown parameters: type, sepa_debit",
"param": "type",
"type": "invalid_request_error"
}
the docs says that type can be 'sepa_debit'...?
Can someone pls hepl me?
You should use Payment Methods API instead of Sources API. If you have an existing Payment Method, you can attach it to a Customer.
You can also create a Payment Method, attach it and start a new payment flow at the same time when creating a Payment Intent.
Related
Is there a way to fix this MailChimp API error in Node.js?
{
type: 'http://developer.mailchimp.com/documentation/mailchimp/guides/error-glossary/',
title: 'Invalid Resource',
status: 400,
detail: "The resource submitted could not be validated. For field-specific details, see the 'errors' array.",
instance: '95a2824e-4f30-4ce4-8c5e-322859d933e4',
errors: [
{
field: 'members.item:0.status',
message: 'Data presented is not one of the accepted values: subscribed, unsubscribed, cleaned, pending.'
}
]
}
What is the API call the Node app is trying to do? Looks like its trying to add a member to a list, so assuming you are making this request POST /lists/{list_id}/members
The required fields in the body needs to be:
{
"email_address": "",
"status": ""
}
Based on the error message, you are not passing in a status in the POST request. Possible values are the following: "subscribed", "unsubscribed", "cleaned", "pending", or "transactional".
I'm trying to use SetupIntents to validate and save a Payment Method and then create a Subscription using it to charge the customer (inmediately and then monthly) for the required amount.
This appears to be working fine:
The Card is validated (including SCA if needed)
The Payment Method is created, attached to customer as default and enabled for future usage with the status SUCEEDED.
The Subscription is created and uses the above payment method
The problem is that Stripe then generates the corresponding Invoice and Payment Intent but the latter with the status "requires_action" whenever the provided Card requires Secure Customer Authorization (SCA), even though the right payment method (enabled for future usage) is being used and the card validation has been already performed.
I thought the whole point of using SetupIntents was precisely to validate the payment method beforehand and be able to charge the customer afterwards.
Is my assumption simply wrong or this is actually possible and I might just be missing something?
Thanks in advance
EDIT: This is the subscription creation code in the backend:
# Set the default payment method on the customer
Stripe::Customer.update(
stripe_customer_id,
invoice_settings: {
default_payment_method: #requested_source
}
)
subscription = Stripe::Subscription.create({
"customer" => stripe_customer_id,
"proration_behavior" => 'create_prorations',
"items" => [
[
"plan" => "#{#stripe_plan_api_id}",
],
],
'default_tax_rates' => [
"#{#stripe_tax_rate_id}",
],
"expand" => ["latest_invoice.payment_intent"]
});
Thanks for the question, Eduardo.
There are a couple ways to create a Subscription while gaining the Customers SCA authentication and permission to charge the card later. Assuming we already have a Stripe Customer object created and their ID is stored in stripe_customer_id. With the flow you have now there are a couple steps:
Create the SetupIntent. Note that if you create it with usage: 'off_session' and the Customer it'll attach the resulting PaymentMethod when confirmed.
setup_intent = Stripe::SetupIntent.create({
customer: stripe_customer_id,
usage: 'off_session',
})
Collect payment details and confirm the SetupIntent using its client_secret on the client which will attach the PaymentMethod to the customer. Note that it will attach but will not be set as the invoice_settings.default_payment_method by default, so you'll need to make a separate API call later to update the Customer (see step 3).
stripe.confirmCardSetup(
'{{setup_intent.client_secret}}',
{
payment_method: {
card: cardElement,
},
}
).then(function(result) {
// Handle result.error or result.setupIntent
});
Update the Customer and set its invoice_settings.default_payment_method equal to the ID of the PaymentMethod on the successfully confirmed SetupIntent.
Stripe::Customer.update(
stripe_customer_id, {
invoice_settings: {
default_payment_method: 'pm_xxxx', # passed to server from client. On the client this is available on the result of confirmCardSetup
}
})
Create the Subscription with off_session: true
subscription = Stripe::Subscription.create({
customer: stripe_customer_id,
proration_behavior: 'create_prorations',
items: [{
plan: "#{#stripe_plan_api_id}",
}],
default_tax_rates: [
"#{#stripe_tax_rate_id}",
],
expand: ["latest_invoice.payment_intent"],
off_session: true,
})
This uses what's called a "Merchant Initiated Transaction" (MIT) for the Subscription's first payment. This is technically okay if the Subscription is created later after the Customer leaves and should technically work.
If the customer is on your site/app when you create the Subscription, there's another flow that is a bit more correct and doesn't require using a MIT exemption for SCA. The flow is the following for a Subscription without a trial:
Collect card details with createPaymentMethod on the client (no SetupIntent)
stripe.createPaymentMethod({
type: 'card',
card: cardElement,
}).then(function(result) {
//pass result to your server.
})
Attach those card details to the Customer
Stripe::PaymentMethod.attach(
"pm_xxx", {
customer: stripe_customer_id
}
)
Update the Customer's invoice_settings.default_payment_method
Stripe::Customer.update(
stripe_customer_id,
invoice_settings: {
default_payment_method: #requested_source
}
)
Create the Subscription (without off_session: true)
subscription = Stripe::Subscription.create(
customer: data['customerId'],
items: [
{
price: 'price_H1NlVtpo6ubk0m'
}
],
expand: ['latest_invoice.payment_intent']
)
Use the Subscription's latest_invoice's payment_intent's client_secret to collect payment details and confirm on the client.
stripe.confirmCardPayment(
'{{subscription.latest_invoice.payment_intent.client_secret}}', { ......
This second payment flow is a bit more correct from an SCA standpoint for getting authorization to charge the card. The second approach is outlined in the guide here: https://stripe.com/docs/billing/subscriptions/fixed-price
We also have a Stripe Sample you can use to experiment here: https://github.com/stripe-samples/subscription-use-cases/tree/master/fixed-price-subscriptions
How to check the status in subscription payment with paypal in e-commerce website
I am applying paypal payment on my website. For subscription payments I always get a pending status, so how can I check when it will succeed and when will it fail?
{
"id":"I-TXXWY50EGMJX",
"state":"Pending",
"description":"Agreement for subscription salon owner",
"start_date":"2020-04-17T07:00:00Z",
"payer":{
"payment_method":"paypal",
"status":"verified",
"payer_info":{
"email":"sb-umuhk1452433#personal.example.com",
"first_name":"John",
"last_name":"Doe",
"payer_id":"Z7CZSRCHLFWGY",
"shipping_address":{
}
}
},
"plan":{
},
"links":[
{
}
],
"agreement_details":{
"outstanding_balance":{
"value":"0.00"
},
"cycles_remaining":"0",
"cycles_completed":"0",
"final_payment_date":"1970-01-01T00:00:00Z",
"failed_payment_count":"0"
},
"httpStatusCode":200
}
If you need to get the status of a Subscription at a later date, you can do so with the appropriate API call: https://developer.paypal.com/docs/api/subscriptions/v1/#subscriptions_get
Your example seems to have been pending because it hadn't started billing yet.
Update:--- Code provided which fixes an issue on the graph which was preventing the API from allowing me to create.
public class CustomerPaymentMethodMaint_Extension:PXGraphExtension<CustomerPaymentMethodMaint>
{
#region Event Handlers
protected virtual void CustomerPaymentMethodDetail_RowSelected(PXCache cache, PXRowSelectedEventArgs e, PXRowSelected del)
{
if (del != null)
{
del(cache, e);
}
if (Base.IsContractBasedAPI)
{
CustomerPaymentMethodDetail row = (CustomerPaymentMethodDetail)e.Row;
PXDefaultAttribute.SetPersistingCheck<CustomerPaymentMethodDetail.value>(cache, row, PXPersistingCheck.Nothing);
}
}
#endregion
}
For the life of me, I cannot figure out what Acumatica is expecting me to send to it to either retrieve or create a customer payment method using the Rest API. It would be greatly appreciated if you could point me in the right direction. The examples we are given are very basic and don't seem to cover any scenarios such as this.
I would assume it would be retrieved using the standard "Retrieval of a Record by Key Fields" as described in the help section.
I have tried using all of the below url structures and it either gives me an "Operation is not valud due to the current state of the object" error, or "More than one entity satisfies the condition".
/entity/Default/6.00.001/CustomerPaymentMethod/{BAccountID}/{PMInstanceID}
/entity/Default/6.00.001/CustomerPaymentMethod/{AcctCD}/{PMInstanceID}
/entity/Default/6.00.001/CustomerPaymentMethod/{BAccountID}
/entity/Default/6.00.001/CustomerPaymentMethod/{PMInstanceID}
/entity/Default/6.00.001/CustomerPaymentMethod/{AcctCD}
While trying to create a payment method I tried using a "PUT" to the CustomerPaymentMethod endpoint with the following json Body (I also tried using the soap friendly names of these fields instead of the label thats in the UI "CCDNUM","CVV","EXPDATE","NAMEONCC"). The error I get returned to me is that "Value" cannot be empty.
{
"CustomerID" : { value: "0000467" },
"PaymentMethod" : { value: "CC" },
"CustomerPaymentMethodDetail" : [
{
"Description" : { value : "Card Number" },
"Value" : { value : "4111111111111111" },
},
{
"Description" : { value : "Expiration Date" },
"Value" : { value : "102020" },
},
{
"Description" : { value : "Name on the Card" },
"Value" : { value : "Test API" },
}
]
}
The following works for me on a project where I'm using APS (American Payment Solutions) as the Processing Center.
Use GET to retreive a collection of Customer Payment Methods for a specific customer:
/entity/Default/6.00.001/CustomerPaymentMethod/?$filter=CustomerID+eq+'000000'
Use GET to return a single Customer Payment Method by ID: (You can find the ID from a record returned by the call above.)
/entity/Default/6.00.001/CustomerPaymentMethod/guid-from-record?$expand=Details
I don't think it's possible to create a Customer Payment Method using a brand new card with the Acumatica API. I think you'll first have to create the payment record using your processing center's API. (APS in my case, but I assume Authorize.net works in a similar fashion.) Then, once the payment record exists at the processor, you can add the Customer Payment Record in Acumatica using a PUT to populate the Payment Profile ID, which is a reference to the tokenized card. From there, you can use the GET calls above to return what you need in order to auth/capture a Sales Order.
I'm working through this now and I'll update my comment once I've learned more.
For me the following worked
/entity/Default/{version}/CustomerPaymentMethod/{customerID}/{customerPaymentMethodId}
Now to get the customerPaymentMethodId this can be done via the customer endpoint when expanding PaymentInstructions.
However unfortunately PaymentInstructions only returns the default payment method for the customer.
Hi I am currently using balanced payments in my meteor application. I can create cards and customers just fine and I can associate the cards to the customers just fine. I run into a problem though when I try to create a debit. Here is the code that I have written which is pretty much taken directly from the balanced docs.
var customer = balanced.Customers.get(user.customer.uri, function (err, customer) {
console.error(err);
console.log(customer);
var customerContext = balanced.Customers.nbalanced(customer);
var debitInfo = {
amount: amount,
appears_on_statement_as: "Statement text",
description: "Some descriptive text for the debit in the dashboard"
};
customerContext.Debits.create(debitInfo, function(err, result) {
console.error(err);
console.log(result);
});
});
I get the error "The requested URL was not found on the server" whenever the above code runs. I found the problem but I'm not entirely sure how to solve it. I went to the balanced dashboard to check the logs and what I found was this.
Date: Fri, 27 Sep 2013, 6:46 AM
Method: POST
URI: /v1/marketplaces/TEST-MPFj4MYWjZc9xt2IjTIni7/v1/customers/CU6jgv9FlavhPyYQ6ObZKDny/debits
Status: 404 NOT FOUND
The request body is here:
{
"appears_on_statement_as": "Statement text",
"amount": 1200,
"description": "Some descriptive text for the debit in the dashboard"
}
Here is the response body:
{
"status": "Not Found",
"category_code": "not-found",
"description": "<p>The requested URL was not found on the server.</p><p>If you entered the URL manually please check your spelling and try again.</p> Your request id is OHM38291020277b11e38b38026ba7cac9da.",
"status_code": 404,
"category_type": "request",
"_uris": {},
"request_id": "OHM38291020277b11e38b38026ba7cac9da"
}
I see that the URI has the marketplace and customer url but I don't know why or what could have caused that to happen because like I said the customer creation, card creation and card association calls all work perfectly.
Any advice would be appreciated.
The balanced api documentation over at https://docs.balancedpayments.com/current/api#create-a-new-debit suggests there is an issue with the requested URL.
The URL in the api module you're using requests
/v1/marketplaces/TEST-MPFj4MYWjZc9xt2IjTIni7/v1/customers/CU6jgv9FlavhPyYQ6ObZKDny/debits
when it should be
/v1/customers/CU6jgv9FlavhPyYQ6ObZKDny/debits
It could also be that it needs the marketplaces uri in there, but there isn't a specification in the docs that matches this type of pattern, plus the '/v1/` suggests its being appended unnecessarily
You haven't given details on the type of package you're using but the issue for this lies in the package in the portion that creates the request URI, or if its not validated perhaps in one of the parameters you've provided.