Why would a Subscription have no Payment Method Token, and how can I map it to a Customer? - braintree

I'm trying to retrieve the customer who created a subscription via its payment_method_token, as described by Braintree developer agf. However, one of my subscriptions has no Payment Method Token. The field comes back as null from the API, and shows up as a blank space in the dashboard:
The docs offer no suggestion that this field could ever be empty. What can cause this to occur, and how can I find out which customer this subscription is associated with?

Full disclosure: I work at Braintree. If you have any further questions, feel free to contact support.
If a payment method is deleted and it has subscriptions connected to it, then the subscription will be canceled, the token will be disassociated from the subscription and you will see this in the control panel.
If there are transactions associated with the subscription, you can get customer information from the transaction objects. In this case, it seems like the subscription never created a transaction before it was deleted so unfortunately you won't be able to trace that back to a customer.

Related

Should I call verifyBuyer for off-session payments

I'm integrating Square payment gateway into our system. And want it to support SCA.
In their dev docs it says that I should call verifyBuyer each time I want to charge CoF. Also, "If a challenge is required, Square automatically displays the challenge to the buyer". It's ok for on-session payments. But what about off-session payments, like cars rental service does - without customer online (automatically)?
In their dev docs it says nothing or I'm missing something.
Did anybody face with such case?
Our docs state:
Important
The SCA flow must not be initiated for a card on file transaction where the buyer is not present. In this scenario, do not call the verifyBuyer function. You can still charge the card but be prepared to handle the CARD_DECLINED_VERIFICATION_REQUIRED error.
Basically, don't call verifyBuyer, and don't pass a token to the payment endpoint. The payment could still technically fail, so you should build functionality to handle that.
https://developer.squareup.com/docs/payment-form/cookbook/verify-buyer-on-cof

Braintree - proration upon subscription cancellation

I have a yearly recurring subscription set up on Braintree. I am trying to cater for a scenario where the user is able to have their subscription cancelled by an admin part way into the yearly cycle.
I am aware of the discounts feature but am unsure how I would apply it in this case or even whether its possible.
Is there a way in Braintree to prorate the amount for the rest of the cycle and credit it back to the user? I would not be doing any of this directly in Braintree but rather through the API via my application that uses Braintree for payments.
Full disclosure: I work at Braintree. If you have any further questions, feel free to contact support#braintreepayments.com.
You can cancel an annual subscription mid-cycle by using the API call to cancel a subscription. Here's a Ruby example, but the Braintree developer docs show examples in all supported SDKs.
result = Braintree::Subscription.cancel("the_subscription_id")
A proration would only apply if a change is made to the subscription price in the middle of a billing cycle. In the event of a cancellation, Braintree won't automatically issue a partial refund; you would have to process the refund yourself. Here is the API call for a partial refund:
result = Braintree::Transaction.refund("transaction_id", "amount")
Also, keep in mind that a cancelled annual subscription will not renew the next year. The only way to "reactivate" the subscription is to create a new one.

How do I trigger a webhook for transaction settlement in sandbox?

I am trying to create a new webhook endpoint for my braintree integration. I added an endpoint to the Control Panel. I am using the Python library and created a a bunch of transactions. Also, I manually settled the transaction using the testing gateway. But I do not get a webhook notification. When is the webhook triggered and I=is there a way to trigger it manually?
Full disclosure: I work at Braintree. If you have any further questions, feel free to contact support.
The Transaction -> Disbursed webhook fires when the transaction has settled, and braintree has begun to move funds from their account to yours. While settling the transaction manually in the control panel would start the process, it does not fire the webhook right away.
There isn't any way to trigger this manually, instead braintree has sample payloads and a way to trigger a "Check" webhook in the control panel.
To answer the question in your comment, this type of webhook does not cover voided transactions.
I also asked a similar question to Braintree support, and the answer may be useful for others, even if I decided to go with Stripe (I found stripe much better after all my tests ;).
Question
Hi,
Just integrating Braintree, but can’t find how I’m supposed to get a transaction confirmation (meaning it has correctly been ‘charged’). When I create a ‘transaction.sale’ (including submitForSettlement) I always get (sandbox) a response indicating the status ‘Submitted for settlement’, and the transaction doesn't go to settled until Braintree globally process it (at night, etc.). I also can’t find a related webhook to get payment confirmation (as I currently get using PayPal - IPN).
When/how can I get a payment confirmation so I can then ‘deliver’ the purchased item? By checking your docs, it’s like you can’t get a confirmation until the next day… how does it work exactly?
Thank you!
Answer
Hi Nacho,
Thanks for reaching out!
A Braintree transaction goes through several steps, the second of which is submitted for settlement. This means that the money has begun to move from the customers account, and is the immediate state of a transaction after being submitted; it's not possible to get an immediate 'settled' or 'complete' status on submission. Transactions in this state will generally move to settling, then settled, within 24 hours, although it can depend on your processing bank.
It is very unusual for a transaction to fail when moving from submitted for settlement to settled, as the amount will have been authorised prior to submission for settlement. Authorising a transaction means the funds are put on hold within the customers account, for a certain timeframe depending on payment method, until they are settled. We get an immediate response from the processing bank as to whether an authorisation is successful, which you'll see in the Braintree_Transaction response object.
As such, you can generally rely on the status of submitted for settlement to reflect a valid, successful transaction.
We don't offer webhooks for transactions - instead, our API is designed to give instant feedback via the response object. Because of this, we only provide webhooks for asynchronous events that aren't triggered by an API call (such as billing a subscription or disbursing funds). We encourage our customers to avail of our API responses, in addition to our reporting system and comprehensive search call options, for any extra functionality they require.
If you wanted to pull updated statuses for transactions, such as to confirm a payment has settled, you could use the Transaction.find() API request, pass in the transaction ID and read in the status from the response object. This could easily be run as a script that iterates through the previous days transaction IDs and updates the status of each on a daily basis.
I hope this explains the transaction process with more clarity and offers you some options!
Kind regards,
Braintree
Just in case it helps!
I also asked kind of the same question to Braintree I got the same answer to check the transaction with Transaction::find() and then asked about the possibility of having a transaction not settled after having a SUBMITTED_FOR_SETTLEMENT status, here is the response, very clear and complete:
Hi Alban,
Thanks for reaching out with this question! Happy to help.
Settlement Declined:
In rare cases, a transaction that has been submitted for settlement will reach a status of settlement declined. For sales, this will only occur with a PayPal transaction. For refunds, this can occur with both PayPal and credit card transactions.
This occurs if the processor declined to settle the sale or refund request, and the result is unsuccessful. This can happen for a number of reasons, but the processor settlement response code may have more information about why the transaction was declined. Again, this status is rare, and only certain types of transactions can be affected.
PayPal sale: We recommend checking the settlement status of all PayPal sale transactions before shipping goods or providing services to customers. To reduce these types of declines, submit your PayPal transactions for settlement either upon creation or within 3 days of creation.
PayPal refund: We recommend contacting PayPal for details on refunds that are Settlement Declined.
Credit card refund: Settlement declines can be hard or soft, just as with authorizations. In regions that support an immediate decline response for refunds, we will return Settlement Declined if the processor responds with a hard decline.
Settlement Pending:
This status indicates that the transaction has not yet fully settled. This status is rare, and it does not always indicate a problem with settlement. Only certain types of transactions can be affected.
--> PayPal sale:
If using multiple partial settlements: Settlement Pending is a normal part of the transaction flow. The parent authorization will remain in this status until all child transactions are settled or the authorization expires. See the multiple partial settlement reference for more details.
If not using multiple partial settlements: Almost all Settlement Pending PayPal transactions will settle without intervention, so we always return a successful result. In general, you can expect these to be updated to Settled within a few days as we confirm their status with PayPal. In the rare case we can't settle a Settlement Pendingtransaction, we'll contact you to resolve the issue.
--> Credit card, Android Pay, and Apple Pay sales: You will only see Settlement Pendingauthorizations if you have contacted us to enable a specific API feature that uses this status.
I hope that provides insight, Alban! Let us know if further questions arise.
Best,
xxxxx.
Braintree

How to check if user subscription is up to date?

I create new customer with credit card using gateway.customer.create
I create new subscription for a customer using gateway.subscription.create
Now when my application starts I have to check if customers subscriptions is still valid. Is there any api endpoint that will allow me to do this?
I am looking for example for a method like this:
isUserSubscribed(customerId)
Maybe also something to get info in which plan user is subscribed (silver,gold,etc)
I work at Braintree. If you have more questions, feel free to reach out to our support team.
When you get a customer from Braintree, you get all of its credit cards and subscriptions:
customer = gateway.customer.find(customerId)
subscriptions = customer.credit_cards.flat_map(&:subscriptions)
You can then look at the customer's subscriptions to find any info you need.

Google Checkout subscription: How to identify the user

We are using Google Checkout - google handled subscriptions. In our html form we are using merchant-item-id parameter to store the subscription plan id and user id, so when Google Checkout send us back the notification for the new orders (merchant-item-id is there) we know what user for what plan to charge. So far this works perfect.
But now, when a month is passed, and Google Checkout start creating the reoccurring orders, there is no merchant-item-id parameter in the notifications they send. So we don't know what user for what plan is charged.
What should we use as user identifier, so we can handle properly the subscription on our site?
Any ideas?
Btw. I know about the "buyer-id" parameter which is send with each new order notification, but that will not work for us, because it is possible that the same google buyer is paying for several of our users accounts.
I would try putting some unique info in "shopping-cart.items.item-1.merchant-private-item-data" to something unique that I can identify the subscription by.
Nikolaj

Resources