Retrieving a Braintree Customer's Subscriptions

Retrieving a Braintree customer's subscriptions

I work at Braintree.

Customers have a credit_cards array, and each credit card has a subscriptions array. So, if you want all the subscriptions for a customer, you can do:

customer.credit_cards.map(&:subscriptions).flatten

Braintree payment gateway - Get customer's subscriptions details


Assuming you have a subscription ID:

# Find the subscription
subscription = Braintree::Subscription.find(sub_id)

# Access the subscription's next billing date
subscription.next_billing_date

Braintree::Subscription.find() returns a Braintree::Subscription result object.

Assuming you have a customer ID:

# Find the customer
customer = Braintree::Customer.find(cust_id)

# Retrieve the customer's first payment method
pm = customer.payment_methods.first

# Retrieve the subscriptions created with that payment method
subscriptions = pm.subscriptions

# Access the subscription's next billing date
subscriptions.first.next_billing_date

Braintree::Customer.find() returns a Braintree::Customer response object. The customer's payment methods can then be retrieved. Subscriptions are associated to payment methods. Once you have a payment method, you can retrieve an array of Braintree::Subscription objects.

search for active subscription for a customer in Braintree payments

It sounds like you want to find active subscriptions for a given customer. According to this answer, "customers have a credit_cards array, and each credit card has a subscriptions array."

With that in mind, you can iterate through each credit card to grab each subscription. Once you have all the customer's subscriptions you can check their status. Here are the relevant Braintree Developer Docs links for .NET:

  • customer.CreditCards
  • creditCard.Subscriptions
  • subscription.Status

Retrieve Braintree Customer ID

Full disclosure: I work at Braintree. If you have any further questions, feel free to contact support.

According to the Braintree developer docs, a Transaction result object has a customerDetails attribute which itself has an id attribute.

As such, you can retrieve the customer id with $result->transaction->customerDetails->id.

Braintree subscription search

With the help from an amazing BT support engineer, we were finally able to figure out a solution to our problem.

The explanation:

When BT returns search results, they gather all associated data and return a large (serialized) response object to the client. In our case some of the subscriptions had a large number of associated transactions, which makes the process of fetching, serializing and returning them to the client slow. When making a request, the BT gateway returns pages in groups of 50 with a default timeout of 60 seconds. Any group with several large response objects will likely time out and produce a 504 error.

The solution:

To avoid this delay, instead of using the items method, we can use the id method from the ResourceCollections class and return just the ids of the objects. With the individual subscription id, we can fetch the individual subscription and only the attributes we need, like so:

subscriptions = gateway.subscription.search(
braintree.SubscriptionSearch.status.in_list(
braintree.Subscription.Status.Active
)
)

subscription_ids = subscriptions.ids

def find_customer_id(id):
subscription = gateway.subscription.find(id)
payment_method = gateway.payment_method.find(subscription.payment_method_token)
return (payment_method.customer_id, subscription.price)

Hope this will help someone else!

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

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.

Can we update payment method for braintree subscription?

Full disclosure, I work at Braintree. If you have any additional questions, contact Support

You can update an existing subscription to use any other payment method that is stored in your Vault. You can do this with an existing payment method, or by creating a new payment method with a paymentMethod()->create() API request.

With that said, the request you provided may work, but I recommend not including the id parameter, as that is reserved for setting a new subscription ID. The subscription ID you are hoping to edit will be placed in the first argument, as you've included in your code. You can simplify the request to look something more like this:

$result = $gateway->subscription()->update('old_subscription_id', [
'paymentMethodToken' => 'new_payment_method_token'
]);

Braintree payment gateway - Get customer information

I work at Braintree. If you want more information than you can easily get on Stack Overflow, please reach out to our support team.

One of the main advantages of payment gateways like Braintree is that they tokenize credit card information without you having to be exposed to it.

Basically, you use Braintree.js to encrypt the card information in the browser so your server never sees it.

Then, you pass that encrypted information on to Braintree. In return, you get a token like "xg67ba" which you can later use to charge the same card again:

result = Braintree::Transaction.sale(
:amount => "100.00",
:customer => {
:first_name => "Dan",
:last_name => "Smith"
},
:credit_card => {
:number => "encryped_credit_card_number",
:expiration_date => "encryped_expiration_date",
:cvv => "encrypted_cvv"
},
:options => {
:store_in_vault => true
}
)

result.transaction.customer_details.id
#=> e.g. "131866"
result.transaction.credit_card_details.token
#=> e.g. "f6j8"

So the next time, it would look like:

result = Braintree::Transaction.sale(
:amount => "10.00",
:customer_id => "131866",
:credit_card => {:cvv => 'encrypted_cvv'}
)

Every credit card is associated with a customer, and so if you just want to charge a customer's only / default card, you can just provide the customer id. Getting the cvv from the customer again (which no one is ever allowed to store) is recommended but not required.



Related Topics



Leave a reply



Submit