In this lunchtime #WPQuickies, I show you how to add WooCommerce customer and order data into your Stripe credit card transactions as metadata.
What Is Stripe?
Stripe is a popular payment gateway that can take online card payments directly from your WooCommerce store.
Stripe doesn’t charge a monthly or yearly fee to use their services.
PayPal can also take card payments but that happens outside your site on PayPal.com for the free version or embedded on your site with their monthly paid subscription pro versions.
Stripe also makes handles recurring billing very easy.
Recurring payments with PayPal is not so easy to set up and manage.
Stripe also offers chargeback and fraud protection which PayPal standard does not.
Many people choose Stripe to handle their online card payments because it’s a free service.
The Stripe payment gateway is not part of the core WooCommerce app.
It is a separate free plugin that needs to be installed after WooCommerce.
How Do Stripe Payouts Work?
Stripe bundles incoming transactions together into a payout which is transferred to your linked bank account.
Payouts can vary depending on your country and the “risk” value Stripe determines your business is operating in.
Full details can be found on the Stripe documentation site at https://stripe.com/docs/payouts.
In general, payouts are delivered into your bank account between 2 and 7 days.
A Reconciliation Problem
Because multiple Stripe transactions can be lumped together in a single payout, this can make it challenging to reconcile invoices in your accounting system.
This is especially true if you have a large volume of low-cost transactions.
You have to log in to your Stripe dashboard and try to identify individual transactions.
The default Stripe transaction only records the date, price, website URL, email address of the customer so it can be a challenge to reconcile that transaction in your accounting system.
By default, WooCommerce adds the product short description and the order ID which can be helpful but we can do better.
Stripe Transactions
Let’s look at a default Stripe transaction.
The transaction has a payment details section where we can see the WooCommerce short description and order number.
Scrolling down, the transaction also has a Metadata section.
This section contains the customer name, customer email address, the WooCommerce Order ID and the website URL.
Having the order ID is helpful and we can log in to our WooCommerce store to see exactly what was purchased.
This works OK if for single purchases but what happens if the customer has purchased many items and you need to reconcile each separately in your accounting software?
That’s going to take some time going back and forth.
An easier way is to add more data to the Metadata section on the Stripe transaction.
Additional Stripe Metadata
Let’s have a look at the metadata section from a Stripe transaction that has been fed more data from a WooCommerce store.
The Payment section stays the same but now we can see additional fields in the metadata for the Stripe transaction.
For this transaction, we are passing in the customers full name, the customer phone number and a list of line items from the order, including line item totals.
The example above shows only one line item but the code will store each line item separately in the metadata allowing you to see exactly what the customer purchased on your WooCommerce store.
That means you shouldn’t need to go back and forth between your store and Stripe to reconcile all your payout transactions.
You can add any customer or product data you need to the Stripe metadata section of the transaction.
WooCommerce Stripe Payment Gateway
Note that this process and code only works with the WooCommerce Stripe Payment Gateway plugin and not the WooCommerce Payments plugin.
The Code
You can find the full code at:
Place this code in your theme’s functions.php file.
The code uses the WooCommerce Stripe plugin filter ‘wc_stripe_payment_metadata’ which provides three arguments 1) Stripe metadata array, 2) The Order object and 3) Prepared Stripe source object (the data object being sent to Stripe).
In this code, we get the order data object and extract the billing company name if it exists as well as the customer name and phone number.
The next bit of code loops through all the order line items, concatenating the line item number, product name, quantity and line item total together into a single line.
The $metadata array is where we store this additional information, which is then passed to Stripe during the payment process.
WooCommerce Customer and Product Data
For this demo, I just inserted added some basic WooCommerce customer and order data but you can add extra fields if needed.
I’ve added some sample data fields in the Gist below for your reference.
You should also have a look at the WC_Order object in the WooCommcerce documentation, especially the $data property
https://woocommerce.github.io/code-reference/classes/WC-Order.html#property_data
Conclusion
So there you have it – a way to add WooCommerce order and customer data to a Stripe transaction metadata.
#WPQuickies
Join me every Thursday at 1 pm Sydney time for some more WPQuickies – WordPress tips and tricks in thirty minutes or less.
Broadcasting live on YouTube and Facebook.
Suggest a #WPQuickies Topic
If you have an WordPress topic you’d like to see explained in 30 mins or under, fill out the form below.
https://forms.gle/mMWCNd3L2cyDFBA57
Watch Previous WPQuickies
How To Use WordPress Functions In a Non-WordPress Custom PHP File
25 Responses
Hi Wil, thanks so much for this code, it’s super helpful! I’m wondering if you know how to send shipping type & cost from Woo to Stripe as a second Line Item Metadata or similar?
Hey Kyla
You can get the shipping cost from $order_data[ ‘shipping_total’ ].
To get the shipping method required an extra step. You have access to the $order object, so.
$shipping = $order->get_shipping_method();
See https://woocommerce.github.io/code-reference/classes/WC-Abstract-Order.html#method_get_shipping_method
Hope that helps!
Wil.
Hello and thank you very much for this article.
Is there any way to do the reverse process, how to store the stripe payment information (4 last digits, credit card type) in the woocommerce order meta data?
Thank you so much
Hi Cesar
There’s no official hook or filter supplied by the WooCommerce Stripe gateway plugin to get credit card details and that’s for security reasons.
Technically this is possible if you have the stripe customer number, you can then retrieve the cards associated with the Stripe customer using https://stripe.com/docs/api/cards/retrieve.
Then you could have access to the Card object https://stripe.com/docs/api/cards/object
{
"id": "card_1JtKLVEJ34ZLkWWBUdXnk1PL",
"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": "US",
"customer": "cus_E2cvrBecka5mCX",
"cvc_check": "pass",
"dynamic_last4": null,
"exp_month": 8,
"exp_year": 2022,
"fingerprint": "axCDBI1gfJ36VZEi",
"funding": "credit",
"last4": "4242",
"metadata": {},
"name": null,
"tokenization_method": null
}
The Card object stores the “brand” and the “last4” card digits.
It’s a bit of work but possible, however, storing credit card numbers, even the last few digits, opens you up to liability and possible criminal charges should that information be leaked from your site.
Regards,
Wil.
Hey Wil!,
Is there anyway to pass description parameter to stripe payment gateway.
Actually, business is registered in India & want to accept non-INR payment.
For that getting the error on my checkout page.
“As per Indian regulations, export transactions require a description. More info here: https://stripe.com/docs/india-exports“”
Yes, in the main code loop insert this code after line 26:
$product_description = $product->get_description();
Line 25 return the WC_Product object into $product so you can use any of the attributes or functions outlined here https://woocommerce.github.io/code-reference/classes/WC-Product.html
Thank you Wil for you response.
But not luck still getting same error.
But after adding webhook endpoint to it. Error got changed.
It seems like now I need to pass customer name, billing shipping address & description to the payment api.
I was wandering if you can help me out with this.
https://prnt.sc/1z00xnw.
I’ll email you directly.
Hi Wil, thank you so much for this code, it’s really helpful.
But the only problem is that the code is working when anyone is logged in and make the payment.
In my site I am allowing customers to place orders as a guest user.
For guest checkout, the metadata’s are not showing up in the captured payment history on Stripe metadata section after the successful payment.
Could you please help me out on this?
Thanks,
Mrinal
Interesting, let me test that out.
There’s nothing in the code that requires a user to be logged in or out. It simply hooks into the Stripe transaction.
Has this only happened the one time or multiple times?
Wil.
Hi will,
This has happened every times whenever I made the payment as guest user.
Please look into this.
Hi,
I am using woo Commerce plugin for wordpress for my Store. Integrated Stripe payment gateway, i have not find any way in WooCommerce to send tax related information against transaction. That will display in stripe tax report section? Is there anyway using wooCommerce i sent information to stripe tax report?
Hi Umair
Do you have “Enable Taxes” checked in the WooCommerce > Settings > General?
Which countries do you have a tax class for?
Do you have an order example that was sent through Stripe card payments that had tax included?
Wil.
Hello,
I want to know the discount PER ITEM. How can I do it. I have searched a lot. Please help!
Thanks!
Hi Israr
You can try to use the get_subtotal() method and then do a subtraction from the total on line 28 to get your per-item discount.
Ref: https://woocommerce.github.io/code-reference/classes/WC-Order-Item-Product.html#method_get_subtotal
Wil.
Hi,
I want to pass product as event name, and sku as event id, order id as normal
for example:
Event Name: xxxyyy(product name)
Event ID: 121332(SKU)
Order id as normal: 123123
Is it possible ?
Please help me
This is not possible with the current setup. You can only add metadata with this method.
Wil.
Hi,
Is there a way to also send Woocommerce custom metadata from each order to Stripe?
Yes, you can add any data that is stored in the database to the function.
Find out where the data is stored in the database and how to extract it and assign it to a variable, then add it to the metadata variable in the code, for example:
$mymetadata1 = "replace this with your DB metadata";
$metadata[ __( 'Meta Data 1', 'woocommerce-gateway-stripe' ) ] = sanitize_text_field( $mymetadata1 );
Hi Wil,
Adding line items as meta data is super useful. I was wondering if you know whether one could generate a Stripe Invoice for every transaction (instead of metadata)?
Hi Tia
Perhaps you are getting terminology mixed up. A transaction is a single purchase and that’s what the WooCommerce Stripe Payment Gateway plugin does.
The code I have here adds transaction meta data and line items to the single transaction.
It’s not possible to bend the Stripe Payment Gateway plugin to create a transaction for every line item. WooCommerce doesn’t work that way.
Thanks,
Wil.
Hi Wil,
Thanks a lot,
How can I create customer metadata instead of payment metadata?
Thanks,
Rodolphe
Hi Rodolphe
You can add any data you can extract from WordPress or WooCommerce in this code snippet.
See the second code snippet for additional order and checkout data fields and look at https://woocommerce.github.io/code-reference/classes/WC-Order.html#property_data
If you’re looking to get user meta data, you will need to make sure the customer is registering and account, then grab the user ID from the order data, then use get_user_meta() to get the data – see https://developer.wordpress.org/reference/functions/get_user_meta/
Hope that helps,
Wil.
Hi Wil,
Awesome article. Quick question on the function.php code. We have all our clients in Stripe, but we want to import their data from Stripe to WooCommerce Subscriptions. We’ve been able to import the users, orders, and subscriptions along with the Customer ID (cus_), but we can not seem to generate / import the Stripe Source ID (src_).
Will adding “The Code” you referenced (linked below) help generate or import the Source ID, so we can add to the subscription billing information? Basically, we want the last 4 digits of the card to show up in the WooCommerce “My Account” > “Payment Methods” screen. Currently, it’s only showing under the Subscriptions screen when we add the Card ID (card_) to the Source ID (src_) area.
https://zeropointdevelopment.com/how-to-add-custom-metadata-to-woocommerce-stripe-purchase/#:~:text=WooCommerce%20Payments%20plugin.-,The%20Code,You%20can%20find%20the%20full%20code%20at%3A,-/**
Hi Billy
No, WooCommerce has no access to the Payment Card number – that’s within Stripe.
You will need to write some custom code to perform an API function request to Stripe to get the card data, probably hooking it into the woocommerce_order_status_completed hook.
You can’t get full access to the card number, but if you have access to the source object then it should return the last 4 digits in the JSON. You can do that by passing the customer_id.
Here’s the JS way of doing that.
var customerService = new StripeCustomerService();
StripeCustomer customer = customerService.Get("cus_BwS21a7fAH22uk");
You’ll get something similar to this back:
JSON: {
"object": "list",
"data": [
{"id":"card_1BY8Hy58hTmWTcG3uosK2up","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":"AU","customer":"cus_JKYFJYUFDap2JQ","cvc_check":"pass","dynamic_last4":null,"exp_month":12,"exp_year":2017,"fingerprint":"yEslkdf4GcxQ","funding":"unknown","last4":"6666","metadata":{},"name":null,"tokenization_method":null}
],
"has_more": false,
"total_count": 1,
"url": "/v1/customers/cus_BvylB8PAVap2JQ/sources"
}
Note “last4″:”6666” in the data object for the test card.