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})
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")
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).
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
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
)