How to expand balance_transaction to get transaction fee from Stripe Webhook response - response

With stripe i am able to expand the balance_transaction object to get the transaction fees for direct payments, i.e. credit card.
This is done by:
$charge = \Stripe\Charge::create(array(
"customer" => $customer->id,
...
"expand" => array("balance_transaction")
)
);
When i use payments with pending transactions, i.e. bank transfer, the fee could not be calculated on charging the payment.
In this case i had to configure a webhook with charge.succeeded and check the source_id that has to match with the initial payment request.
I wonder how to get the fees out of the webhook response. blance_transaction is not expanded. Any hints?

Sadly, it is not possible. This would be a webhook preference.
According to their Docs page on expand parameter:
This parameter [n. expand] is available on all API requests, and applies to the response of that request only.

Related

How to change Rails object fields after it's been paid via Stripe Checkout?

In my application, a user can create a draft of an object, and then on a "finalise" view they can check if they only want the standard price or one of the two extra features as well (e.g. their entry being featured on the platform) - these are stored as three separate products each with their own price because I want to be able to track them separately in the future.
I am using Checkout for payments and my backend is Rails.
I am listening to webhooks, but I don't know how I could actually modify the object in question, since I can't see any webhook request body that contains the information I need.
What I imagine I'd need is something like this: "there has been a successful charge of $x related to your object with id 123, and the charge included product prod_asdf and prod_sdfg", and then I could update e.g. the paid and featured boolean fields of my object.
This seems like a no-brainer, since the products and prices are actually handled by Stripe and they are passed to the checkout session, I don't see why I can't access them from the webhooks?
EDIT: I'm wondering if passing necessary metadata to the Session object and then using the same metadata listening to a checkout.session.completed event is a good idea.
You can link a Checkout Session back to your Listing object by including the related object ID in the metadata (https://stripe.com/docs/api/checkout/sessions/object#checkout_session_object-metadata) when you create the Checkout Session. When you listen for checkout.session.completed events, the event will come with a Checkout Session object. You can easily link the Checkout Session back to your Listing object by checking the metadata and it also has an amount_total field so that will tell you the total payment amount.
You can get the products included in a session from line_items (https://stripe.com/docs/api/checkout/sessions/object#checkout_session_object-line_items). Unfortunately, line_items is not included in the webhook event by default since it is expandable (https://stripe.com/docs/expand). After receiving the checkout.session.completed event you can use the ID to retrieve the Checkout Session with line_items expanded like this:
session = Stripe::Checkout::Session.retrieve(
id: 'cs_test_xxx',
expand: ['line_items'],
)
line_items = session.line_items
Alternatively, you can just retrieve the Checkout Session's line items (https://stripe.com/docs/api/checkout/sessions/line_items) like this:
line_items = Stripe::Checkout::Session.list_line_items('cs_test_D3OF4MY1VGflR8idkewd795t8MLd4PwA3wxdLCHikdRFTIkBecH6FKij', {limit: 5})

Retrieving Stripe Charge through metadata

I'm trying to get a Charge using Stripe API.
Everything is good but I don't understand why this request is not working:
Stripe::Charge.all(metadata: { project_id: an_id })
I got error:
Stripe::InvalidRequestError: Received unknown parameter: metadata
Here's what a response look like:
{"id":"ch_1BQIXjGrTKCCbjGtKVJOKzbg","object":"charge","amount":1000,"amount_refunded":0,"application":null,"application_fee":"fee_1BQIXlEsrND8ZkheXtsfgQWj","balance_transaction":"txn_1BQIXlGrTKCCbjGtpSDEu34m","captured":true,"created":1511196887,"currency":"eur","customer":"cus_BnuMP3mm0iEFL8","description":"Don","destination":"acct_1BEzwEEsrND8Zkhe","dispute":null,"failure_code":null,"failure_message":null,"fraud_details":{},"invoice":null,"livemode":true,"**metadata":**{"donation_amount":"10","donation_fees":"0","donation_id":"21110","donation_referer_id":"417","donation_reward_id":"2120",**"project_id":"501"**,"project_name":"Arcadia - Le Concert Classique des youtubers","user_city":"Segré","user_country":"FR","user_email":"simon-chretien#hotmail.fr","user_first_name":"Simon","user_id":"23038","user_last_name":"Chrétien"},"on_behalf_of":"acct_1BEzwEEsrND8Zkhe","order":null,"outcome":{"network_status":"approved_by_network","reason":null,"risk_level":"normal","seller_message":"Payment complete.","type":"authorized"},"paid":true,"receipt_email":"simon-chretien#hotmail.fr","receipt_number":"1097-0153","refunded":false,"refunds":{"object":"list","data":[],"has_more":false,"total_count":0,"url":"/v1/charges/ch_1BQIXjGrTKCCbjGtKVJOKzbg/refunds"},"review":null,"shipping":null,"source":{"id":"card_1BQIXcGrTKCCbjGtKktLMM42","object":"card","address_city":null,"address_country":null,"address_line1":null,"address_line1_check":null,"address_line2":null,"address_state":null,"address_zip":null,"address_zip_check":null,"brand":"Visa","country":"FR","customer":"cus_BnuMP3mm0iEFL8","cvc_check":"pass","dynamic_last4":null,"exp_month":10,"exp_year":2020,"fingerprint":"aMPkqWKgq4dQUnWy","funding":"credit","last4":"8073","metadata":{},"name":"simon-chretien#hotmail.fr","tokenization_method":null},"source_transfer":null,"statement_descriptor":null,"status":"succeeded","transfer":"tr_1BQIXlGrTKCCbjGtjFk4oC0D","transfer_group":"group_ch_1BQIXjGrTKCCbjGtKVJOKzbg"},
As you can see there's a metadata => project_id in response
What am I doing wrong ?
As one of the comments has said you can use retrieve if you are looking to return one charge. You would have to pass the charge id to the method:
Stripe::Charge.retrieve('ch_1BQIXjGrTKCCbjGtKVJOKzbg')
The documentation that you are looking for would be under List all charges. all is actually an alias for list. Based on the documentation to accomplish what you are looking at doing, you could return all the Stripe Charges and then search for the project_id within metadata.
Depending on how many charges you have this seems like it would be overkill returning all of your charges. Instead consider only return the charges based on the customer
Only return charges for the customer specified by this customer ID.
Stripe::Charge.list(customer: "cus_BnuMP3mm0iEFL8")
# or
Stripe::Charge.all(customer: "cus_BnuMP3mm0iEFL8")

Is it possible to change the amount from authorize to capture in ActiveMerchant?

I'm doing a function that authorize first the user's credit card information. From that I can get a response and able to save the transaction_id or authorization key w/c can be use to capture the money from Credit Card.
But I need to do it separate way, just to authorize the credit card info first.
Since, authorizing the card requires the initial amount like for ex:
credit_card = ActiveMerchant::Billing::CreditCard.new(
:number => '4111111111111111',
:month => '8',
:year => '2009',
:first_name => 'Tobias',
:last_name => 'Luetke',
:verification_value => '123'
)
# initial amount - 1000
response = gateway.authorize(1000, credit_card)
My BIG question now is that, is it possible to use the #capture:
with different amount, now 2000
gateway.capture(2000, response.authorization)
Yeah I think it is possible since both capture and authorize are standalone server calls,
Authorization -
You request an authorization when a customer makes a purchase. An authorization, provided by the customer’s card issuing bank, confirms the cardholder’s ability to pay, ensuring that the customer's credit card account is in good standing with sufficient funds to complete the purchase.
Capture -
After providing a service/product to the customer, you ‘capture’ the relevant information from the authorization and submit it in a capture/settlement request that your processor uses to initiate a funds transfer between the customer's credit card account and your checking account.
Source
So by definition it should be possible, but you would not know if the user will be able to pay the amount you intend to capture(if the amount is higher than the one in authorize call).

Get a list of the charges on a Stripe account connected via Stripe Connect

How do you get a list of customer charges on a connected Stripe account?
For the main account, I use this:
Stripe::Charge.all(customer: stripe_id).data
But I can't find any documentation on getting charges off of another account without changing the Stripe.api_key for that call alone, which seems like a terrible practice.
The answer is to add the stripe_account key to the options hash of the Stripe API call:
Stripe::Charge.all(
{ customer: stripe_id },
stripe_account: connected_account_id
).data

Braintree payment gateway: Dealing with "payment_method_token"?

I'm new to brain tree payment gateway. I can't understand that what is payment_method_nonce (token provided by end user) or how this token is generated ?
Also I dont know how to get the customer card details, how to store it, and how to do transactions with the "payment_method_token"
result = Braintree::PaymentMethodNonce.create("A_PAYMENT_METHOD_TOKEN")
nonce = result.payment_method_nonce.nonce
Can any body explain how to create or get A_PAYMENT_METHOD_TOKEN?
The paymentmethodtoken is a unique identifier for the customer's credit card that we use to make purchases.
If you check the result object you can extract the payment method token from it and can be stored in your side for future transaction for the same user without entering the card details.
This is required to save the payment method nonce as a payment method token. The payment method nonce can only be used once, where the token is a reusable value that will not expire.
You’ll need to first create the customer and payment method in one call, and then use the payment method token from the result object to create the subscription. Keep in mind that you will need to first create a plan in the Control Panel, but you can override most of the plan details when you create the subscription.
After you create a Customer with a stored payment method you can use the returned token to subscribe a user to a plan. This article explains it well:
https://developers.braintreepayments.com/guides/recurring-billing/overview
A Real Time Example by Site point Team on How to Integrate Braintree Can be found in the bellow link:
Integrate Braintree Payments into Rails
payment_method_nonce is the params that your braintree form submit to your controller.
You can use nonce_from_the_client = params['payment_method_nonce'] to create braintree Transaction
result = Braintree::Transaction.sale(
:amount => "100.00",
:payment_method_nonce => nonce_from_the_client
)

Resources