Stripe API and PHP: Relationship of PAYOUTS to Payment Intent / Charges - php

I'm new with STRIPE, and I've been reading the documentation for STRIPE, and was task to create a list of payouts to a connected account (type is standard). Also, I have to show the details, under those PAYOUT, all the payments included in it.
However I can't see any relation to PAYOUTS with PAYMENT INTENTS/CHARGES, is it possible to know all those payments included in the PAYOUTS ? We are creating STANDARD connect accounts for our users.

I had the same challenge, and had to go thru 4 supporters, tell my needs over and over again, before i finally got the right hint and could complete my checks and cron jobs. I provide my solution here to save others the same experience:
$po = 'po_sadfahk.....'; // payout id (i do a loop of payouts)
\Stripe\Stripe::setApiKey($stripeSecretKey);
$balanceTransactions = \Stripe\BalanceTransaction::all([
'payout' => "$po",
'type' => 'charge',
'limit' => 100, // default is 10, but a payout can have more pi's
'expand' => ['data.source'],
]);
foreach ($balanceTransactions->data as $txn) {
// my invoice id is added in description when creating the payment intent
echo "Invoice: {$txn->description}\n";
echo "Created: {$txn->created}\n";
echo "Available: {$txn->available_on}\n";
// in source we find the pi_id, amount and currency for each payment intent
$charge = $txn->source;
echo "pi: {$charge->payment_intent}\n";
$amount = $charge->amount/100;
echo "$amount {$charge->currency}\n";
}
Output (cropped to relevant data):
{
"object": "list",
"data": [
{
"id": "txn_1ISOaSGqFEoKRtad...",
"object": "balance_transaction",
"amount": 25000,
"available_on": 1615680000,
"created": 1615131127,
"currency": "dkk",
"description": "Invoice 44",
...
"fee": 530,
"fee_details": [
{
"amount": 530,
"application": null,
"currency": "dkk",
"description": "Stripe processing fees",
"type": "stripe_fee"
}
],
...
"source": {
"id": "ch_1ISOaRGqFEoKR...",
"object": "charge",
"amount": 25000,
...
"paid": true,
"payment_intent": "pi_1ISOa3GqFE...", // here we go!
"payment_method": "pm_1ISOaRGqFE...",
"payment_method_details": {
"card": {
"brand": "visa",
...
},
"type": "card"
},
...
},
"status": "available",
"type": "charge"
}
],
"has_more": false,
"url": "/v1/balance_transactions"
}

Kudos to Kim for his answer. I also went through a number of supporters in Stripe to no avail. His post sorted me out.
The code below is a mere Python 3.10 translation from Kim's code above
po = 'po_<some_payment_id>'
balanceTransactions = stripe.BalanceTransaction.list(
payout=po,
type='charge',
limit=100,
expand=['data.source']
)
for txn in balanceTransactions.data:
print("Invoice: {0}".format(txn.description))
print("Created: {0}".format(txn.created))
print("Available: {0}".format(txn.available_on))
charge = txn.source
print("pi: {0}".format(charge.payment_intent))
amount = charge.amount/100
print("{0} {1}".format(amount, charge.currency))

I'm not sure you'll have that access for a Standard Account, but if it you do, you'll be able to list all of the Balance Transactions associated with that Payout, which will have a reference to the Payment Intent in the source field for any Payment Intents.

Related

Webhooks JSON in PHP

I've been working on a web-based system using PHP. The system is linking to the payment gateway using API and webhooks for payment notification. I've worked on everything else but webhooks are foreign to me. I've subscribed to webhooks and the payment gateway is supposed to send in JSON via the url submitted when creating webhooks. Below is the sample JSON.
{
"topic": "buygoods_transaction_received",
"id": "2133dbfb-24b9-40fc-ae57-2d7559785760",
"created_at": "2020-10-22T10:43:20+03:00",
"event": {
"type": "Buygoods Transaction",
"resource": {
"id": "458712f-gr76y-24b9-40fc-ae57-2d35785760",
"amount": "100.0",
"status": "Received",
"system": "Lipa Na M-PESA",
"currency": "KES",
"reference": "OJM6Q1W84K",
"till_number": "000000",
"sender_phone_number": "+254999999999",
"origination_time": "2020-10-22T10:43:19+03:00",
"sender_last_name": "Doe",
"sender_first_name": "Jane",
"sender_middle_name": null
}
},
"_links": {
"self": "https://sandbox.kopokopo.com/webhook_events/2133dbfb-24b9-40fc-ae57-2d7559785760",
"resource": "https://sandbox.kopokopo.com/financial_transaction/458712f-gr76y-24b9-40fc-ae57-2d35785760"
}
}
I need to capture some fields like OJM6Q1W84K,100.0 etc and store them into my db. How do I capture the JSON? The rest will be easy for me once I figure out that one. Thanks guys.

Paypal PAYOUT_NOT_AVAILABLE

My sandbox account return this error when creating a payout
{
"name": "PAYOUT_NOT_AVAILABLE",
"message": "You live in a country that is not allowed to send this payout.",
}
This error is not listed in https://developer.paypal.com/docs/api/payments.payouts-batch/#errors
The account is configured in México (MX) and the official documentation includes MX in the payouts docs.
Am I missing something? Can't find any doc that excludes specific countries.
Just some exceptions for Argentina, Brazil and Malaysia.
It also defiens Mexican currency in the features
https://developer.paypal.com/docs/payouts/#payouts-features
I happened to find a similar endpoint but the weird thing is that it's not listed in the main APIs menu but it seems to be working, for reference check:
https://developer.paypal.com/docs/payouts/test
Update: it seems to be related to the test data that's used in the note field, even if using batch payouts the following changed the result status:
{
"sender_batch_header": {
"sender_batch_id": "Payouts_2018_100007",
"email_subject": "You have a payout!",
"email_message": "You have received a payout! Thanks for using our service!"
},
"items":[
{
"recipient_type": "EMAIL",
"amount": {
"value": "500",
"currency": "MXN"
},
"note": "POSPYO001",
"sender_item_id": "201403140001",
"receiver": "ss36#business.example.com",
"alternate_notification_method": {
"phone": {
"country_code": "52",
"national_number": "4491110560"
}
},
"notification_language": "sp-SP"
}
]
}
A single payout looks like this:
{
"sender_payout_header":
{
"sender_batch_id": "1524086406556",
"email_subject": "This email is related to simulation"
},
"items": [
{
"recipient_type": "EMAIL",
"receiver": "payouts-simulator-receiver#paypal.com",
"note": "POSPYO001",
"sender_item_id": "15240864065560",
"amount":
{
"currency": "USD",
"value": "1.00"
}
}]
}
I was having the same issue and it was because my country(India) name is present in supported countries list of PayPal but i got to know about PayPal Commerce Platform availability where it is not supporting India. Check below link
https://developer.paypal.com/docs/api/reference/country-codes/?mark=countries#paypal-commerce-platform-availability
My work is only on sandbox account of paypal for testing so i simply created new test account of country US.
Possibly your paypal account is from any country listed in above link. Please check country of your main paypal account.

Lottery on wordpress using php and json

I am currently building a website for my guild (on a video game).
The video game (Guild wars 2) provide us a feed of everything being done inside the guild in a json file (user joining, withdraw of money, deposit of items, kick, etc...).
Since I have this feed, auto-updated, I would like to setup a lottery, working on the following :
- guild member (user) buy a ticket => deposit golds in our bank (displayed as deposit)
- display this information on the website => user "x" has bought a ticket at H:M:DD:MM:Y (for example)
- at the end of the month, script to random a winner from this list of users (this random must include only tickets bought between date A & B)
I have managed to write a little code, and it is working, only to display a list of users and their actions :
<?php
$apikey = '(My API key)';
$guildkey = '(My guild key)';
$jsontest =file_get_contents ('https://api.guildwars2.com/v2/guild/'.$guildkey.'/log?access_token='. $apikey);
$json = json_decode($jsontest,true);
foreach($json as $member)
{
if ($member['coins'] > 1)
print "Guild member "."".$member['user'].""." has bought a ticket for ".$member['coins']." golds"." ";
}
?>
Here a little example of how the guild wars 2 api output is :
{
"type": "upgrade",
"item_id": 77729,
"count": 1,
"action": "completed",
"id": 896815,
"time": "2017-02-23T14:26:29.000Z",
"user": "Lehi.5091",
"upgrade_id": 668
},
{
"id": 896814,
"time": "2017-02-23T14:26:29.000Z",
"type": "upgrade",
"upgrade_id": 668,
"action": "queued"
},
{
"type": "upgrade",
"item_id": 77729,
"count": 1,
"action": "completed",
"id": 896810,
"time": "2017-02-23T14:26:28.000Z",
"user": "Lehi.5091",
"upgrade_id": 668
As intended, it does display what I want, here the working code
If you have tips or anything about how to this, I'll gladly take them.
Thanks for your help,

Not able to place the order using paypal in magento 2 rest

I am developing an e-commerce mobiloe application using magento 2 rest apis only.This is the flow for making the REST API calls for order placement.
1.Create a cart
api -->{{url}}/index.php/rest/V1/carts/mine
This api will return a unique cart id
2.Add products to cart
api --> {{url}}/index.php/rest/V1/carts/mine/items
body ->
{
"cart_item": {
"quote_id": cartId,
"sku": skuName,
"qty": 1
}
}
3. Estimate Shipping Methods
url --> {{url}}/index.php/rest/V1/carts/mine/estimate-shipping-methods
body ->
{
"address": {
"region": "Trivandrum",
"region_id": 12,
"region_code": "CA",
"country_id": "IN",
"street": [
"Amstor house",
"Eramam"
],
"telephone": "5656565454",
"postcode": "670390",
"city": "Kazhakuttam",
"firstname": "Peter",
"lastname": "K",
"same_as_billing": 0,
"save_in_address_book": 0
}
}
This will return all possible shipping methods based on shipping address.In my case the result is
[
{
"carrier_code": "freeshipping",
"method_code": "freeshipping",
"carrier_title": "Free Shipping",
"method_title": "Free",
"amount": 0,
"base_amount": 0,
"available": true,
"error_message": "",
"price_excl_tax": 0,
"price_incl_tax": 0
}
]
4)Save shipping information
url --> {{url}}/index.php/rest/V1/carts/mine/shipping-information
body data ->
{
"addressInformation": {
"shipping_address": {
"region": "Trivandrum",
"region_id": 12,
"region_code": "CA",
"country_id": "IN",
"street": [
"Amstor house",
"Eramam"
],
"telephone": "5656565454",
"postcode": "670390",
"city": "Kazhakuttam",
"firstname": "Peter",
"lastname": "K",
},
"billing_address": {
"region": "Trivandrum",
"region_id": 12,
"region_code": "CA",
"country_id": "IN",
"street": [
"Amstor house",
"Eramam"
],
"telephone": "5656565454",
"postcode": "670390",
"city": "Kazhakuttam",
"firstname": "Peter",
"lastname": "K",
},
"shipping_method_code": "freeshipping",
"shipping_carrier_code": "freeshipping"
}
}
This will return all possible payment methods. Here i am using paypal_express for payment.
5. Payment using paypal plugin
Here i will pay the amount using paypal cordova plugin.Also configured the IPN [{{url}}/paypal/ipn/]in paypal account
This api will return the following data,
{
"client": {
"environment": "sandbox",
"paypal_sdk_version": "2.14.4",
"platform": "Android",
"product_name": "PayPal-Android-SDK"
},
"response": {
"create_time": "2016-11-19T05:25:46Z",
"id": "PAY-5VS11410F5341972MLAX6ETA",
"intent": "sale",
"state": "approved"
},
"response_type": "payment"
}
5.Save payment and place order
url --> {{url}}/index.php/rest/V1/carts/mine/payment-information
data ->
{
"cartId": 3,
"billingAddress‌​": {
"region": "Trivandrum",
"region_id": 12,
"region_code": "CA",
"country_id": "IN",
"street": [
"Amstor house",
"Eramam"
],
"telephone": "5656565454",
"postcode": "670390",
"city": "Kazhakuttam",
"firstname": "Peter",
"lastname": "K"
},
"paymentMethod": {
"method": "paypal_express"
}
}
But this api will returning
{
"message": "PayPal gateway has rejected request. Invalid token (#10410: Invalid token)."
}
Is there any api missing in the above flow for capturing payments.Please help me.
Paypal Express payment method doesn't support online capturing. There is no way to get a full order creation flow like on Checkout via Magento API interface. It is impossible to change the order state and process payments. As a workaround try the following:
Create a custom payment method
Enable for REST API only(Not on website checkout page)
While making payment using rest api use this method (after successful payment using you android/ios SDK)
After placing the order make send transaction id(PAY-xxxxx) return by paypal sdk payment to save trasaction.(tell your server side tio implement this call).
I am writting a complete atrticle regarding this step by step. I will let you know when it is done.
Place Order by PayPal Rest API
For the Place order by the Paypal rest API, you need an active cart with shipping and billing address
By default, we need to follow the few setups for placing the order
• Step 1. Create an empty cart
• Step 2. Add products to the cart
• Step 3. Set the shipping address
• Step 4. Set billing address
• Step 5. Set the delivery method
• Step 6. Apply a coupon (if you have)
• Step 7. Set the payment method
• Step 8. Place order
After steps 6 follow below APIs
We need to call the below APIs one by one for placing the order with Paypal
Create Paypal Express Token
URL : {you website
url}/rest/default/V1/paypalapi/createpaypalexpresstoken
Method: POST
Set Bearer Token in the Hearer (if customer ) for the guest user no need to set it
Content-type : JSON
Body For guest users:
{
"cart_id":"5QWFYZdyccucvgD2QMLDCp5fhjmaH2xg",
"cancel_url":"cancel_url",
"return_url":"return_url"
}
Body For Customer user:
{
"cart_id": 22,
"cancel_url": "cancel_url",
"return_url": "return_url"
}
You will get the response like this :
[
{
"code": 200,
"token": "EC-4MD50688YD296870K",
"paypal_urls":{
"start": "https://www.sandbox.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token=EC-4MD50688YD296870K&useraction=commit",
"edit": "https://www.sandbox.paypal.com/cgi-bin/webscr?cmd=_express-checkout&useraction=continue&token=EC-4MD50688YD296870K"
}
}]
Explanation
you need to redirect the customer to the {start URL } and after making the payment, PayPal will redirect the user with two params in the redirect URL "payer_id" and "token" Both values you need to call in the below API
Set Payment Method On Cart
URL : {you website
url}/rest/default/V1/paypalapi/setpaymentmethodoncart
Method: POST
Set Bearer Token in the Hearer (if customer ) for the guest user no
need to set it
Content-type : JSON
Body For guest users:
{
"cart_id": "5QWFYZdyccucvgD2QMLDCp5fhjmaH2xg",
"payer_id": "9T3GV67ZSL378",
"token": "EC-4MD50688YD296870K",
"payment_method": "paypal_express"
}
Body For Customer user:
{
"cart_id": 22,
"payer_id": "9T3GV67ZSL378",
"token": "EC-4MD50688YD296870K",
"payment_method": "paypal_express",
"customer_id": 141
}
You will get the response like this :
[
{
"code": 200,
"selected_payment_method": {
"code": "paypal_express",
"title": "PayPal Express Checkout"
}
}
]
Place Order
URL : {you website url}/rest/default/V1/paypalapi/placeorder
Method: POST
Set Bearer Token in the Hearer (if customer ) for the guest user no
need to set it
Content-type : JSON
Body For guest users:
{ "cart_id": "5QWFYZdyccucvgD2QMLDCp5fhjmaH2xg" }
Body For Customer user:
{ "cart_id": 22, "customer_id": 141 }
You will get the response like this :
[ { "code": 200, "order_number": 000000142 } ]
Here is the link to the Paypal Rest API module
https://github.com/santosh-gaggle/paypal-rest-api
In case someone still looking the solution.
In the time I'm answering this, You will need to create a Magento 2 module to process the payment ID.
After you receive the response from in example Paypal android SDK.
Below is the JSON format that you can send to Magento endpoint :
for logged user : PUT /V1/carts/mine/order
for guest : PUT /V1/guest-carts/:cartId/order
Referrence : http://devdocs.magento.com/swagger
The "paypal_express_payment_payload" is just a custom attribute to hold the paypal payment response previously from android SDK.
{
"paymentMethod": {
"method": "paypal_express",
"additional_data": {
"paypal_express_payment_payload": "{\"create_time\":\"2017-06-15T23:13:52Z\",\"id\":\"PAY-2LB41725NU654612TLFBRIUQ\",\"intent\":\"sale\",\"state\":\"approved\"}"
}
}
}
To process the "paypal_express_payment_payload" data, you can implement a Interceptor in your Magento 2 module :
di.xml
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<type name="Magento\Paypal\Model\Express">
<plugin name="mymodule_magento_paypal_model_express_plugin"
type="Mycompanyorpersonal\Mymodule\Plugin\Paypal\Model\Express"
sortOrder="99999"
disabled="false" />
</type>
</config>
Mycompanyorpersonal\Mymodule\Plugin\Paypal\Model\Express.php
You can find the full PHP codes in my following gist : https://gist.github.com/feelinc/de817030e00adc7ff7001de1807c1835
If you use the below to run a post query replace runPostQuery with your curl request. this will pass a token that already has been successful to magento 2.
$payment['paymentMethod'] = ['method' =>'paypal_express',
'additional_data' => array (
'paypal_express_checkout_token' => $request->query->get('token'),
'paypal_express_checkout_redirect_required' => false,
'paypal_express_checkout_payer_id' => $request->query->get('PayerID')
)];
$completedPayment = $this->runPostQuery('carts/mine/payment-information', $headers, json_encode($payment));
You will need to create a plugin to add the last transaction id to the payment see the above comment, but the above payload to payment-information will allow you to get past _placeOrder function in Paypal\Model\Express.php
The paypal_express_checkout_token is the token passed back to the browser from paypal same as PayerId this allows to check the payment, which will return successful and not require a redirect, but is not the payment reference just the action token.

How to add and retrieve metafields to order when adding new order via api

I am trying to add metafields to new order as follows:
{ "order": {
"line_items": [
{
"title": "Test Order item 1",
"price": 0.00,
"grams": "1700",
"quantity": 1, "taxable": false
}
],
"metafield": {
"namespace": "inventory",
"key": "amazonOrderId",
"value": 123456789,
"value_type": "integer" },
"email": "rahul#testOrder.com",
"total_tax": 0.00 } }
The order is being created on shopify admin panel but on retrieving same order metafields are not returned. I am not sure where to find added metafield, is it added or not. Please help.
Thanks
Ok, so I found how to store and retrieve metafields for an order in Shopify..
we need to make a POST call to /admin/orders/{order_id}/metafields.json with following format:
{
"metafield": {
"namespace": "global",
"key": "amazonID",
"value": "dfsfsd",
"value_type": "string"
}
}
and then to retrieve the metafields for that particular order we use following url:
/admin/orders/{order_id}/metafields.json
Reference: https://docs.shopify.com/api/reference/metafield#create

Categories