PayPal REST API get total amount - php

I'm using PayPal rest-api-sdk-php the latest version. Everything is working fine in terms of creating the payment and executing the payment and getting all the relevant data back but have decided I want the total amount paid via paypal. It returns a JSON object back, example below
"transactions": [
{
"amount": {
"total": "20.00",
"currency": "GBP",
"details": {
"subtotal": "17.50",
"tax": "1.30",
"shipping": "1.20"
}
},
"description": "Payment description",
"invoice_number": "55e30dbd55cea",
"item_list": {
"items": [
{
"name": "Ground Coffee 40 oz",
"price": "7.50",
"currency": "GBP",
"quantity": "1",
"description": "Ground Coffee 40 oz",
"tax": "0.30"
},
{
"name": "Granola bars",
"price": "2.00",
"currency": "USD",
"quantity": "5",
"description": "Granola Bars with Peanuts",
"tax": "0.20"
}
]
},
}
],
I have tried calling $payment->transactions->amount->total but get an error. Just wondered if someone can shed some light. Thanks

"transactions" is an array, so you need to iterate through it.
If you want the first total amount, try $payment->transactions[0]->amount->total;

Related

Paypal Integration in PHP checkout/v2/UpdateOrder REFERENCE_ID_NOT_FOUND

I try to implement paypal express checkout in a way that users are able to manipulate their order after they logged in with Paypal and when they are done, click "bux now" and the actual payment is capured.
To do so, I created the order with paypal before with intend "Authorize". The user logs into paypal and comes back to my shop to manage the order. When done, I want to use paypals updateOrder Call to apply the users changes. But It always bounces with error REFERENCE_ID_NOT_FOUND.
Here is the documentation:
https://developer.paypal.com/api/orders/v2/#orders_patch
Here is, what I send to Paypal.
[{
"op": "replace",
"path": "\/purchase_units\/#reference_id=='default'",
"value": [{
"reference_id": "2295037",
"description": "Your order at Shop",
"custom_id": "Shop Id 2295037",
"soft_descriptor": "Shopname",
"invoice_id": "2295037",
"amount": {
"currency_code": "EUR",
"value": 59.98,
"breakdown": {
"item_total": {
"currency_code": "EUR",
"value": 50.4
},
"shipping": {
"currency_code": "EUR",
"value": 0
},
"discount": {
"currency_code": "EUR",
"value": 0
},
"tax_total": {
"currency_code": "EUR",
"value": 9.58
}
}
},
"items": [{
"name": "Product 1",
"description": "Product Descr. 1",
"sku": "1019879",
"unit_amount": {
"currency_code": "EUR",
"value": 16.8
},
"tax": {
"currency_code": "EUR",
"value": 3.19
},
"quantity": "1",
"category": "PHYSICAL_GOODS"
}, {
"name": "Product 2",
"description": "Product Descr. 2",
"sku": "1024593",
"unit_amount": {
"currency_code": "EUR",
"value": 33.61
},
"tax": {
"currency_code": "EUR",
"value": 6.38
},
"quantity": "1",
"category": "PHYSICAL_GOODS"
}],
"shipping": {
"name": {
"full_name": "John Doe"
},
"address": {
"address_line_1": "Badensche Str. 24",
"address_line_2": "",
"admin_area_2": "Berlin",
"postal_code": "10715",
"country_code": "DE"
}
}
}]
}]
The answer from Paypal is "REFERENCE_ID_NOT_FOUND". Paypal itself suggests 'default' if there is only one purchase unit (which it is). I also tried to replace 'default' with the reference_id in our system (which was provided with the createOrder call) or paypal´s own transactionId (which is provided through the endpoint anyway). The error is always the same.
How can I change this call so that Paypal accepts it and updates the order in its system?
It turned out, that I had a mistake by sending the value as an array insterad of an object. With the shops own reference Id it worked after fixing this issue.
The Error code-Reposne by paypal was misleading:
"value": [{
->
"value": {

Is it possible extract and merge a single json object from multiple json files?

Sorry for the confusing title. I am having a bit of an issue here merging some JSON files. I need to merge all the products into one array in a separate file.
I have a directory full of same structured json files. I am using glob to select all files and decode->append-->encode json files into one large file.
Here is my code:
<?php
$files = glob("*.json");
$newDataArray = [];
foreach($files as $file){
$thisData = file_get_contents($file);
$thisDataArray = json_decode($thisData);
$newDataArray[] = $thisDataArray;
}
$newDataJSON = json_encode($newDataArray);
file_put_contents("merged.json",$newDataJSON);
?>
Now, the above code seems to work great but I only want to extract all the products.
Quick example of what I need to achieve.
File1.json
{
"status": true,
"user": {
"username": "sally",
"avatar": "/images/default-avatar.png",
"products": [
{
"id": "35vR4hr",
"title": "Picture 1",
"image": null,
"quantity": {
"min": 1,
"max": 1
},
"price": 2,
"currency": "CAD",
"stock_warning": 1,
"type": "service",
"stock": 9223372036854776000
},
{
"id": "na1Id4t",
"title": "Picture 2",
"image": null,
"quantity": {
"min": 1,
"max": 1
},
"price": 0.75,
"currency": "CAD",
"stock_warning": 3,
"type": "service",
"stock": 9223372036854776000
}
]
}
}
File2.json
{
"status": true,
"user": {
"username": "Jessica",
"avatar": "/images/default-avatar.png",
"products": [
{
"id": "wjiefi94",
"title": "Picture 3",
"image": null,
"quantity": {
"min": 1,
"max": 1
},
"price": 2,
"currency": "CAD",
"stock_warning": 1,
"type": "service",
"stock": 9223372036854776000
},
{
"id": "n34idwi",
"title": "Picture 4",
"image": null,
"quantity": {
"min": 1,
"max": 1
},
"price": 0.75,
"currency": "CAD",
"stock_warning": 3,
"type": "service",
"stock": 9223372036854776000
}
]
}
}
I want the data to be merged like:
merged.json
{
"products": [
{
"id": "wjiefi94",
"title": "Picture 1",
"image": null,
"quantity": {
"min": 1,
"max": 1
},
"price": 2,
"currency": "CAD",
"stock_warning": 1,
"type": "service",
"stock": 9223372036854776000
},
{
"id": "n34idwi",
"title": "Picture 2",
"image": null,
"quantity": {
"min": 1,
"max": 1
},
"price": 0.75,
"currency": "CAD",
"stock_warning": 3,
"type": "service",
"stock": 9223372036854776000
},
{
"id": "n34idwi",
"title": "Picture 3",
"image": null,
"quantity": {
"min": 1,
"max": 1
},
"price": 0.75,
"currency": "CAD",
"stock_warning": 3,
"type": "service",
"stock": 9223372036854776000
},
{
"id": "n34idwi",
"title": "Picture 4",
"image": null,
"quantity": {
"min": 1,
"max": 1
},
"price": 0.75,
"currency": "CAD",
"stock_warning": 3,
"type": "service",
"stock": 9223372036854776000
}
]
}
I hope this makes sense. I feel like I have hit a dead end here. Any help is greatly appreciated.
would it be possible for you to call an external tool like "jq"? handling json (just like csv), especially with many files, is not something you should be doing manually.
btw, your example does not have commas between products 2 and 3 and 3 and 4.
Your new code on line 5 should probably read like this with the array brackets? Otherwise you are overwriting the contents of the last files:
$thisDataArray[] = json_decode($thisData);
And why are you merging products from Sally and Jessica into the same user? Maybe you can just extract all the products objects into one file?
More of a code review than an answer, hope it helps ;)

How to link PayPal webhook and user?

I think I'm over looking something incredibly simple here.
When I create a new billing agreement through the PayPal PHP SDK I'm returned to my store by the following URL..
/paypal-success?success=true&token=EC-3K353628LH3197445
I have created a WebHook for the Subscription Created event that posts JSON as follows
{
"id": "WH-5UR49681MC703253M-3S161814MB664705V",
"event_version": "1.0",
"create_time": "2018-03-17T17:21:47.120Z",
"resource_type": "Agreement",
"event_type": "BILLING.SUBSCRIPTION.CREATED",
"summary": "A billing subscription was created",
"resource": {
"agreement_details": {
"outstanding_balance": {
"value": "0.00"
},
"num_cycles_remaining": "0",
"num_cycles_completed": "0",
"next_billing_date": "2018-03-17T10:00:00Z",
"last_payment_date": "2018-03-17T17:21:44Z",
"last_payment_amount": {
"value": "1.00"
},
"final_payment_due_date": "1970-01-01T00:00:00Z",
"failed_payment_count": "0"
},
"description": "x",
"links": [{
"href": "api.sandbox.paypal.com/v1/payments/billing-agreements/I-55KA5N9GPPJW",
"rel": "self",
"method": "GET"
}],
"shipping_address": {
"recipient_name": "test buyer",
"line1": "Spitalfields Arts Market, 112 Brick Lane,",
"city": "London",
"state": "London",
"postal_code": "E1 6RL",
"country_code": "GB"
},
"id": "I-55KA5N9GPPJW",
"state": "Active",
"payer": {
"payment_method": "paypal",
"status": "verified",
"payer_info": {
"email": "jamie-buyer#x.com",
"first_name": "test",
"last_name": "buyer",
"payer_id": "Q3TZFN4F7NHJ6",
"shipping_address": {
"recipient_name": "test buyer",
"line1": "Spitalfields Arts Market, 112 Brick Lane,",
"city": "London",
"state": "London",
"postal_code": "E1 6RL",
"country_code": "GB"
}
}
},
"plan": {
"curr_code": "USD",
"links": [],
"payment_definitions": [{
"type": "REGULAR",
"frequency": "Month",
"frequency_interval": "1",
"amount": {
"value": "49.99"
},
"cycles": "0",
"charge_models": [{
"type": "TAX",
"amount": {
"value": "0.00"
}
},
{
"type": "SHIPPING",
"amount": {
"value": "0.00"
}
}]
}],
"merchant_preferences": {
"setup_fee": {
"value": "1.00"
},
"auto_bill_amount": "YES",
"max_fail_attempts": "0"
}
},
"start_date": "2018-03-17T00:00:00Z"
},
"links": [{
"href": "https://api.sandbox.paypal.com/v1/notifications/webhooks-events/WH-5UR49681MC703253M-3S161814MB664705V",
"rel": "self",
"method": "GET"
},
{
"href": "https://api.sandbox.paypal.com/v1/notifications/webhooks-events/WH-5UR49681MC703253M-3S161814MB664705V/resend",
"rel": "resend",
"method": "POST"
}]
}
That token generated when the user is redirected back to my store does not appear to be in the WebHooks JSON.
How do you link your PayPal users once they are redirected back to your store to the incoming WebHooks?
The token returned in your success url is used to activate the agreement after the user accepts the agreement on PayPal. Once you activate the agreement you can retrieve the agreement id. That id is in your web hook under resources/id. "id": "I-55KA5N9GPPJW". There may be a better way to deal with this but I created a subscription table that associates the agreement id to the user id and a transactions table that has the agreement id and the associated webhook information.

Magento 2 REST API Assigning Thumbnail Image On Configurable Products

I'm currently able to add products via the Magento 2 REST API (Magento 2.2.1) but have 1 major problem.
With Single Products everything is working great and I'm able to create them with images and assign images as thumbnails, etc. However with Configurable Products the images aren't being assigned as thumbnails, but are still successfully uploaded.
Here's a Single Product REST call which works fine:
{
"product": {
"sku": "08130056-DARKNAVY",
"name": "Dakine Campus 25L Backpack - Dark Navy",
"price": "44.9900",
"status": "1",
"visibility": "4",
"type_id": "simple",
"weight": "1.0000",
"extension_attributes": {
"stock_item": {
"manage_stock": 1,
"qty": "1.0000",
"is_in_stock": true
}
},
"options": [],
"tier_prices": [],
"media_gallery_entries": [{
"media_type": "image",
"label": "Dakine Campus 25L Backpack - Dark Navy",
"position": "0",
"disabled": 0,
"types": [],
"file": "\/media\/catalog\/product\/i\/\/i\/m\/image_8735.jpg",
"content": {
"base64_encoded_data": "IMAGE BASE64 HERE",
"type": "image\/jpeg",
"name": "08130056 DARKNAVY"
}
}, {
"media_type": "image",
"label": "Dakine Campus 25L Backpack - Dark Navy",
"position": "0",
"disabled": 0,
"types": ["image", "small_image", "thumbnail", "swatch_image"],
"file": "\/media\/catalog\/product\/i\/\/i\/m\/image_8736.jpg",
"content": {
"base64_encoded_data": "IMAGE BASE64 HERE",
"type": "image\/jpeg",
"name": "08130056 DARKNAVY"
}
}],
"attribute_set_id": 62,
"custom_attributes": [{
"attribute_code": "manufacturer",
"value": "503"
}, {
"attribute_code": "color",
"value": "452"
}, {
"attribute_code": "short_description",
"value": "<span>The Campus 25 litre follows the lead of our popular Campus 33 litre back-to-school backpack with a slightly smaller volume-great for smaller students or smaller workloads. Packed with all the same features including a large top compartment with a padded laptop sleeve and room for books and binders, a fleece lined pocket for sunglasses, a slim organiser pocket, and a handy insulated pocket to keep lunch and snacks cool. Padded shoulder straps and an adjustable sternum strap ensure a perfect fit. Dimensions = <\/span>18.5 x 12 x 9\" [ 47 x 31 x 23cm ]<div><ul><li>Limited Lifetime Warranty<\/li><li>600D Polyester<\/li><li>Fits most 14\" laptops<\/li><li>Insulated cooler pocket<\/li><li>Organiser pocket<\/li><li>Fleece lined pocket for sunglasses<\/li><li>Mesh side pockets<\/li><li>Adjustable sternum strap<\/li><\/ul><\/div><br>"
}, {
"attribute_code": "barcode",
"value": "610934177053"
}, {
"attribute_code": "category_ids",
"value": [350]
}, {
"attribute_code": "meta_title",
"value": "Dakine Campus 25L Backpack - Dark Navy"
}, {
"attribute_code": "meta_keyword",
"value": "dakine,campus,25l,backpack,-,dark,navy,urbansurfer,urban,surfer,mens,backpacks"
}, {
"attribute_code": "meta_description",
"value": "Dakine Campus 25L Backpack - Dark Navy - Shop online for a large range of including Dakine with fast, free shipping from an official stockist."
}, {
"attribute_code": "news_from_date",
"value": "2017-12-22 10:56:59"
}, {
"attribute_code": "news_to_date",
"value": "2018-01-22 10:56:59"
}]
},
"save_options": true
}
And here's a configurable product where for some reason the thumbnail, image, small_image and swatch aren't being set:
{
"product": {
"sku": "226787-705-29",
"name": "Levis Dawson Lace Up Boots - Dark Brown",
"price": "99.9900",
"status": "1",
"visibility": "4",
"type_id": "configurable",
"weight": 1,
"extension_attributes": {
"stock_item": {
"manage_stock": 1,
"qty": "0.0000",
"is_in_stock": true
}
},
"options": [],
"tier_prices": [],
"media_gallery_entries": [{
"media_type": "image",
"label": "Levis Dawson Lace Up Boots - Dark Brown",
"position": "0",
"disabled": 0,
"types": [],
"file": "\/media\/catalog\/product\/i\/\/i\/m\/image_8637.jpg",
"content": {
"base64_encoded_data": "IMAGE BASE64 HERE",
"type": "image\/jpeg",
"name": "226787 705 29"
}
}, {
"media_type": "image",
"label": "Levis Dawson Lace Up Boots - Dark Brown",
"position": "0",
"disabled": 0,
"types": [],
"file": "\/media\/catalog\/product\/i\/\/i\/m\/image_8638.jpg",
"content": {
"base64_encoded_data": "IMAGE BASE64 HERE",
"type": "image\/jpeg",
"name": "226787 705 29"
}
}, {
"media_type": "image",
"label": "Levis Dawson Lace Up Boots - Dark Brown",
"position": "0",
"disabled": 0,
"types": ["image", "small_image", "thumbnail", "swatch_image"],
"file": "\/media\/catalog\/product\/i\/\/i\/m\/image_8639.jpg",
"content": {
"base64_encoded_data": "IMAGE BASE64 HERE",
"type": "image\/jpeg",
"name": "226787 705 29"
}
}],
"attribute_set_id": 44,
"custom_attributes": [{
"attribute_code": "manufacturer",
"value": "537"
}, {
"attribute_code": "color",
"value": "453"
}, {
"attribute_code": "short_description",
"value": "<span>Levis Dawson Lace Up Boots Dark Brown from Levi's are a great style option for your off-duty look. Featuring a soft leather outer, this pair has padded ankles for comfort and will team well with denim.<\/span><br><ul><li>Leather Comfort Insole<\/li><li>Anatomical Design<\/li><li>High Shock Absorption<\/li><li>Genuine Leather Coating<\/li><\/ul>"
}, {
"attribute_code": "barcode",
"value": ""
}, {
"attribute_code": "category_ids",
"value": [347]
}, {
"attribute_code": "meta_title",
"value": "Levis Dawson Lace Up Boots - Dark Brown"
}, {
"attribute_code": "meta_keyword",
"value": "levis,dawson,lace,up,boots,-,dark,brown,urbansurfer,urban,surfer,levi's,mens,shoes"
}, {
"attribute_code": "meta_description",
"value": "Levis Dawson Lace Up Boots - Dark Brown - Shop online for a large range of including Levi's with fast, free shipping from an official stockist."
}, {
"attribute_code": "news_from_date",
"value": "2017-12-15 14:56:33"
}, {
"attribute_code": "news_to_date",
"value": "2018-01-15 14:56:33"
}]
},
"save_options": true
}
You can see that "types" is set the same for both calls but is just seemingly ignored for the Configurable Product, there is no trace of anything in the Magento 2 logs either.
This is consistently happening with every Configurable Product we have, yet all Single Products are working great. Child Products do not have any images set at all as intended. I've also tested adding a Configurable Product with no child products and the results are the same.
I can manually set the thumbnail, etc in the Magento 2 admin, but I need this to be automated via these REST calls. I've tried all sorts and just can't pin down what's going wrong.
I had the same problem.
Solution:
I used catalogProductAttributeMediaGalleryManagementV1 to list all media gallery items (via GET ".../V1/products/TEST_SKU/media": list "id" and other fields).
After selecting the first image (with "media_type" = "image") I created a new JSON object.
{
"entry":
{
"id": 1086,
"media_type": "image",
"label": "This is my image description",
"position": 1,
"disabled": false,
"types": [ "image", "small_image", "thumbnail" ]
}
}
After sending it using PUT (e.g. ".../V1/products/TEST_SKU/media/1086") the image saved correctly.

PHP array with Paypal response Array

I have been having an issue trying to get the value of one field from a Paypal response array. I have been working on it for hours and can not figure it out.
I want the value of $related_resources->sale->id, however I tried
$resource_id = $related_resources->sale->id;
AND
foreach ($related_resources as $related_resource) {
$resource_id = $related_resource->sale-id;
}
and neither have worked. Hopefully someone will be able to help me out and save me from this headache.
"related_resources": [ { "sale": { "id": "000000000000", "state":
"completed", "amount": { "total": "0.01", "currency": "USD", "details": {
"subtotal": "0.01" } }, "payment_mode": "INSTANT_TRANSFER",
"protection_eligibility": "ELIGIBLE", "protection_eligibility_type":
"ITEM_NOT_RECEIVED_ELIGIBLE,UNAUTHORIZED_PAYMENT_ELIGIBLE",
"transaction_fee": { "value": "0.01", "currency": "USD" }, "receipt_id":
"00000000000", "parent_payment": "PAY-000000000000000", "create_time":
"2017-04-28T14:59:05Z", "update_time": "2017-04-28T14:59:05Z"...

Categories