How to make a shopify API request inside webhook callback script - shopify

I am writing my first Shopify app that will unpublish a product once its inventory level goes below threshold.
For that I register a webhook with callback URL http://example.com/script.php that will be called by Shopify once product update event occurs.
In script.php how do I obtain Shopify API token to make PUT request to products/update to unpublish it?
Here is my script.php so far (I know I am missing hmac validation but that is not the point):
<?php
if($_SERVER['REQUEST_METHOD'] == 'POST'){
session_start();
require 'shopify.php';
$api_key = 'api_key';
$secret = 'secret';
$sc = new ShopifyClient($_SERVER['HTTP_X_SHOPIFY_SHOP_DOMAIN'], $_SERVER['HTTP_X_SHOPIFY_HMAC_SHA256'], $api_key, $secret);
$inventory = $_POST['inventory_quantity'];
$old_inventory = $_POST['old_inventory_quantity'];
if($inventory <= 0){
$args = array("product" => array("id" => $_SERVER['HTTP_X_SHOPIFY_PRODUCT_ID'], "published" => false));
$sc->call("PUT","/admin/products/".$_SERVER['HTTP_X_SHOPIFY_PRODUCT_ID'].".json",$args);
}
}
I am trying to use $_SERVER['HTTP_X_SHOPIFY_HMAC_SHA256'] but obviously that is wrong.

Shopify sends you the name of the shop in the header of every webhook. So your webhook can now authenticate the incoming call, and with the shop name, you simply query your persistence layer for the matching shop credentials. If you find the shop, you can open up an API session very easily, since you have the two things you need:
shopify domain name of the store
shopify access token
Note that a better way to hide products is to consider listening to the orders webhooks, which provide orders and products, and then query the inventory level of the product sold. Working off of product/update webhooks could be super obnoxious in terms of the number of calls you might have to process in comparison to orders.

Related

Twitter Ads API error: INSUFFICIENT_USER_AUTHORIZED_PERMISSION. How to solve it?

I am trying to perform a request to the twitter Ads API in my dev environment. I am already registered to get access to this service.
I have received a confirmation e-mail like this:
Your application (ID:12345678) has been approved for the Twitter Ads API program and your organization has been granted a Developer license for Read/Write access. ...
This is why I suppose to have my APP ready to query the Ads API.
Besides that I have information about the APP (tokens and secrets) in the page https://developer.twitter.com/en/apps but I can't find any reference to the account_id, mentioned in the official documentation.
Advertising accounts are registered on ads.twitter.com and identified
in the API by account_id. Advertising accounts link directly to funding
sources and leverage content from one or more Twitter user accounts as
‘promotable users’. Each advertising account can grant permission to
one or more Twitter user accounts. The advertising account, or “current
account,” is represented in nearly every URL executed as an in-line
:account_id parameter.
Following this post I have create the follow code in oder to get access to the Twitter Ads API:
$settings = array(
'oauth_access_token' => env('TWITTER_ACCESS_TOKEN'),
'oauth_access_token_secret' => env('TWITTER_ACCESS_TOKEN_SECRET'),
'consumer_key' => env('TWITTER_CONSUMER_KEY'),
'consumer_secret' => env('TWITTER_CONSUMER_SECRET'),
);
$url = 'https://api.twitter.com/1.1/followers/ids.json';
$getfield = '?screen_name=J7mbo';
$requestMethod = 'GET';
$twitter = new TwitterAPIExchangeService($settings);
$data = $twitter->setGetfield($getfield)
->buildOauth($url, $requestMethod)
->performRequest();
dd($data);
The previous code is working (I am not querying Ads API. But the next one ( querying the Ads Api) is not working:
$url = 'https://ads-api.twitter.com/5/accounts';
$requestMethod = 'GET';
$twitter = new TwitterAPIExchangeService($settings);
$data = $twitter->buildOauth($url, $requestMethod)->performRequest();
dd($data);
{"errors":[{"code":"INSUFFICIENT_USER_AUTHORIZED_PERMISSION","message":"User 2222222222 is not authorized to make this request. Please have them reauthorize with your client application APPNAme."}],"request":{"params":{}}}
What am I missing?
I have found a solution. I don't know if this is the only one but it works.
We must instal Twurl. Twurl is a curl-like application, tailored specifically for the Twitter API.
Install twurl in your system. $ sudo gem install twurl
Set authorization to twurl acceess your twitter APP. $ twurl authorize --consumer-key xxxxx --consumer-secret xxxxx
That is the output for the prevoius command: Go to https://api.twitter.com/oauth/authorize?oauth_consumer_key=xxxx&oauth_nonce=ffff&oauth_signature=bbb&oauth_signature_method=HMAC-SHA1&oauth_timestamp=1556889574&oauth_token=ddd&oauth_version=1.0 and paste in the supplied PIN
Open the browser copy and paste the provided URL https://api. .... version=1.0
You will be redirected to a page asking to confirm the authorization. Confirm it.
You will receive a message: 'You've granted access to APP_Name! Next, return to APP_Name and enter this PIN to complete the authorization process. PIN = 09010101'.
Just copy the PIN number and paste back in the terminal and hit enter.
You will get a message in the terminal Authorization successful.
Go to yor APP_Name page https://developer.twitter.com/en/apps/123456 and go to Keys and tokens section. You need to regenerate the Access token & access token secret. Hit the button 'regenerate'
Once it is regenerate you can get access to the api trough twurl in your terminal: $ twurl -H "ads-api.twitter.com" "/5/accounts". Please note that today (May-2019) I am using number 5 in "/5/accounts". You must to check your version at your date.
Now you can get access to the Twitter Ads API trough curl in php also.
Create a class TwitterAPIExchangeService (I am in Laravel 5.8). You can get the class in this post.
Use the follow code with your keys:
$settings = array(
'oauth_access_token' => env('TWITTER_ACCESS_TOKEN'),
'oauth_access_token_secret' => env('TWITTER_ACCESS_TOKEN_SECRET'),
'consumer_key' => env('TWITTER_CONSUMER_KEY'),
'consumer_secret' => env('TWITTER_CONSUMER_SECRET'),
);
//Regular Twitter API
$url = 'https://api.twitter.com/1.1/followers/ids.json';
$getfield = '?screen_name=J7mbo';
//Ads Twitter API
//$url = 'https://ads-api.twitter.com/5/accounts';
//$getfield = '';
$requestMethod = 'GET';
$twitter = new TwitterAPIExchangeService($settings);
$data = $twitter->setGetfield($getfield)
->buildOauth($url, $requestMethod)
->performRequest();
dd($data);
Need to regenerate keys and tokens. after that its work for me

How to get Inventory for merchant fulfilled product using amazon mws api?

I am using MWS api for fetching inventory using ListInventorySupplyAsyncSample call but it gives inventory only for amazon fulfilled product.
How to get inventory for product fulfilled by merchant?
The ListInventorySupply call is part of the Fulfillment Inventory API which deals exclusively with FBA (Fulfillment by Amazon) stock located in one of the Amazon warehouses.
Your own (merchant fulfilled) stock in your own (non-Amazon) warehouse is probably managed best outside Amazon, but should be available to "download" form Amazon by using the RequestReport call with a ReportType of _GET_MERCHANT_LISTINGS_ALL_DATA_. I haven't tried this myself, though.
You may see through my code
use meertism's package from GitHub
`<?php
$amazonSellerId =
$amazonMWSAuthToken =
$amazonAWSAccessKeyId =
$amazonSecretKey =
$amazonMarketPlaceId =
$client = new MCS\MWSClient([
'Marketplace_Id' => $amazonMarketPlaceId,
'Seller_Id' => $amazonSellerId,
'Access_Key_ID' => $amazonAWSAccessKeyId,
'Secret_Access_Key' => $amazonSecretKey,
'MWSAuthToken' => $amazonMWSAuthToken // Optional. Only use this key if you are a
third party user/developer
]);
$reportId = $client->RequestReport('_GET_MERCHANT_LISTINGS_DATA_');
sleep(20);
$report_content = $client->GetReport($reportId);
foreach($report_content as $i)
{
if($i['seller-sku'] == sku)
{ $qty=$i['quantity'];
}
}
echo $qty;`
I am currently using the Amzpecty API service to get real-time inventory of Amazon sellers given the ASIN.

Express Checkout Return URL C#

I am using the PayPal API in C# and calling the .SetExpressCheckout() with a return url of:
http://www.MyWebsite.com/Success?transactionId={DynamicToken}
Is it possible that PayPal isn't returning the transactionId token that I have specified or is that improbable? I am trying to diagnose a few random errors (from hundreds of successful transactions) and wondering would it ever drop the parameter I have specified in the Return URL?
Also is it safe to assume that if PayPal returns 'Successful' but I DONT call .DoExpressCheckout() that no money has been taken and I can start again?
SetExpressCheckout will always return a response something like this:
NVP Response:
TOKEN=EC-8FL80454MK5202351
TIMESTAMP=2015-09-10T02:53:36Z
CORRELATIONID=bff60e96e81c4
ACK=Success
VERSION=109.0
BUILD=000000
and you will need to redirect to the checkout page
https://www.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token=EC-8FL80454MK5202351
Once the buyer login and completes, it will redirect to your returnurl+EC-token+payerid
http://index.php?action=ECreturn&token=EC-8FL80454MK5202351&PayerID=7SGRP23PR8MWY
So, PayPal always does return the EC-Token and after this you will need to call Doexpresscheckout API to complete the payment without this the transaction is not complete.
VERSION = 109.0
METHOD = DoExpressCheckoutPayment
TOKEN = EC-8FL80454MK5202351
PAYMENTACTION = Sale
PAYERID = 7SGRP23PR8MWY
AMT = 0.01
for example if you have a return url like this
RETURNURL = index.php?action=ECreturn?test=1
then it after Setexpresscheckout is complete, Paypal will redirect to the following URL
index.php?action=ECreturn?test=1&token=EC-5K62958L49079615&PayerID=7SGRP23PR8MWY

Get Buyer Email from Omnipay Paypal Express

I integrated the Omnipay PayPal express.
After the completePurchase() I need the PayPal buyer email adress.
I can access the Transaction ID with $data['PAYMENTINFO_0_TRANSACTIONID'] and also the Payer ID through $_GET['PayerID'].
Any ideas how to get the buyers email?
After completePurchase(), you need to fetch the checkout datas:
$response = $gateway->fetchCheckout($parameters)->send();
$data = $response->getData();
// you can check the full received data
print "<pre>";
var_dump($data);
And in this array, you've got a $data["EMAIL"] variable, wich stores the payer's e-mail address.
Regards!
P.s.: For more information and a TL;DR disquisition, check this.

How do you obtain a WeChat access_token certificate from api.wechat.com?

This site tries to explain the process: http://admin.wechat.com/wiki/index.php?title=Access_token
The problem is nowhere do they tell you where to get the AppID or what exactly the secret is.Has anyone else succeeded in communicating with WeChat?
Essentially we # WeChat have 2 types of accounts, subscription and service. Subscription account only gives you access to the Message API which allows for receiving messages and autoresponses and allows you to broadcast to your users once a day. Subscription accounts are also grouped in a category in your contacts under subscription.
A service account gives you an APP ID and APP SECRET which allows you to generate an access token which is needed for pretty much all the other API's apart from the Message API. A service account displays in the user's contact list under the main chats in between all your other normal contacts. You can only broadcast to each of your users once a month on a service account.
If you have a service account you will get the APP ID and APP SECRET from admin.wechat.com -> login -> function -> advanced -> developer mode -> Just under your token you will see the APP ID and APP SECRET
To see what type of account you have go to admin.wechat.com -> login and then look at the top right of the screen next to your account name you will see your account name and just above that it will either say subscription account or service account.
If you want to test all the API's I recommend going to the developer sandbox environment where you get full access to all the API's: How does link with href for Line and Wechat?
Please note your number needs to be in the international format so 072 111 2233 you have to enter as +27721112233
Login http://admin.wechat.com
[advanced] --> [Developer Mode], you will got your Appid & AppSecret.
You don't have a wechat OA account?
Join [WeChat Space] https://plus.google.com/communities/102783597675617808511
You may go to http://dev.wechat.com/ to sign up for a developer account.
After you sign up, you will get your App ID and AppKey via your signup email.
Then, you can go to http://admin.wechat.com/wiki/index.php?title=Main_Page to obtain more information.
I wrote a code snippet on github that explains the entire process. The code is for django but can be used with any python framework
here is a snippet
import xml.etree.ElementTree as ET
from wechat.views import WeChatView
MyCustomView(WeChatView):
token = "ad4sf65weG7Db6ddWE"
on_message(self, message):
root = ET.fromstring(message)
from = root[1].text
message_type = root[3].text
content = root[4].text
print('from: {}'.format(from))
print('message type: {}'.format(message_type))
print('content: {}'.format(content))
The full code is here https://github.com/tawanda/django-wechat
Here's my code,maybe you can try it.
//Getting access_token from customize menus
static function get_access_token($appid,$secret){
$url="https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=".$appid."&secret=".$secret;
$json=http_request_json($url);//here cannot use file_get_contents
$data=json_decode($json,true);
if($data['access_token']){
return $data['access_token'];
}else{
return "Error occurred while geting the access_token";
}
}
//Though URL request is https',cannot use file_get_contents.Using CURL while asking the JSON data
function http_request_json($url){
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,$url);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$result = curl_exec($ch);
curl_close($ch);
return $result;
}