ApplicationCharge and test mode - shopify

If I enable test mode for a (recurring) charge in my Shopify App during beta
charge = ShopifyAPI::RecurringApplicationCharge.create(:name => 'myplan',
:price => 4.99, :return_url => 'http://yourapp.com/charges/confirm',
:test => true)
what should I do when the App goes out of beta? Can I just update the existing (recurring) charge, or do I have to create a new (recurring) charge?

You should cancel the test charge and create a new one. You will need to redirect the shop owner to the new charge confirmation url, as they'll need to accept the new charge. It's not possible to change the charge without the shop owner's permission as far as I know, except to cancel it.

Related

Is PayPal permission required to use SetExpressCheckout for a third party?

We are processing payments on behalf of third parties using SetExpressCheckout. It appears to work correctly even though the third party has not granted us permissions. Are we doing it correctly?
From what I have understood, in order to process payment for a third party the third party should go to Tools > API credentials > Grant API Permission in their PayPal account and grant permission to our API username to Use Express Checkout to process payments. However, we have noticed two issues with this:
If the third-party PayPal account is just a personal account (not a business account) then there is no option to grant API permissions
Even if the non-business third-party PayPal account doesn't grant this permission we are still able to take payment into their account.
So the question is, is it actually necessary for a third party to grant us this permission in order for us to be able to process payments which are crediting their PayPal accounts?
In case you need more information, here is a cut-down version of the PHP code we are using to start the SetExpressCheckout request. We are specifying the third-party using the SUBJECT parameter of the request, this parameter is filled in with the email address of the third-party's PayPal account.
// Parameters for SetExpressCheckout
$requestParams = array(
'METHOD' => 'SetExpressCheckout',
'VERSION' => $this->_version,
'PAYMENTREQUEST_0_DESC' => "Order number",
'PAYMENTREQUEST_0_AMT' => 10,
'PAYMENTREQUEST_0_CURRENCYCODE' = 'EUR',
'PAYMENTREQUEST_0_ITEMAMT' => 10,
'RETURNURL' => "http://SUCCESS_URL_TO_RETURN_TO",
'CANCELURL' => "http://FAILURE_URL_TO_RETURN_TO",
'USER' => 'OUR_API_USERNAME',
'PWD' => 'OUR_API_PASSWORD',
'SIGNATURE' => 'OUR_API_SIGNATURE',
'SUBJECT' => 'THIRD_PARTY_EMAIL'
);
// Options for curl
$curlOptions = array (
CURLOPT_URL => 'https://api-3t.paypal.com/nvp',
CURLOPT_VERBOSE => 1,
CURLOPT_SSL_VERIFYPEER => true,
CURLOPT_SSL_VERIFYHOST => 2,
CURLOPT_CAINFO => 'cacert.pem', //CA cert file
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_POST => 1,
CURLOPT_POSTFIELDS => http_build_query($requestParams)
);
// Send the curl request
$ch = curl_init();
curl_setopt_array($ch,$curlOptions);
$response = curl_exec($ch);
// Handle possible errors
if (curl_errno($ch)) {
//Handle errors
} else {
// Handle success
}
curl_close($ch);
If third-party accounts are not required to grant us permission then we can simplify setup of PayPal by simply asking for their PayPal account's email address, and not have to bother them with granting permissions.
Many thanks for any information you can give.
There are two ways to make API calls on behalf of others. 1) Grant API permissions from merchant PayPal account to API caller OR 2) Use SUBJECT NVP variable with the merchant PayPal account email address('SUBJECT' => 'THIRD_PARTY_EMAIL').
So you can make the API calls on behalf of the merchant just by using the SUBJECT NVP variable with merchant PayPal account email address, here the merchant no need to grant API permissions to you.

How to make a shopify API request inside webhook callback script

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.

Reccuring charge change activation

I've built an app which implements the recurring charge api and I have some issues...
In the docs (https://help.shopify.com/api/reference/recurringapplicationcharge) it states:
Each shop may have only one recurring charge per application.
When a new RecurringApplicationCharge is activated for a shop that already has a recurring charge for that application, the existing recurring charge will be cancelled and replaced by the new charge. The new recurring charge will then activate.
This means that upgrading and downgrading a user’s recurring charge or plan is straightforward; just change their plan, have them accept, and Shopify takes care of the rest.
So I have some users which I have on either "test" recurring charge and some on "trial"... how can I "force" them to accept the new plan (change of the name of the plan or price)...
The thing that bugs me is that you're supposed to check for any active reccuring charges, example from the app sample on github (https://github.com/Shopify/example-ruby-app/blob/master/02%20Charging%20For%20Your%20App/app.rb):
def create_recurring_application_charge
# checks to see if there is already an RecurringApplicationCharge created and activated
unless ShopifyAPI::RecurringApplicationCharge.current
recurring_application_charge = ShopifyAPI::RecurringApplicationCharge.new(
name: "Gift Basket Plan",
price: 9.99,
return_url: "https:\/\/#{APP_URL}\/activatecharge",
test: true,
trial_days: 7,
capped_amount: 100,
terms: "$0.99 for every order created")
# if the new RecurringApplicationCharge saves,redirect the user to the confirmation URL,
# so they can accept or decline the charge
if recurring_application_charge.save
#tokens[:confirmation_url] = recurring_application_charge.confirmation_url
redirect recurring_application_charge.confirmation_url
end
end
end
the method in charge of checking for an active payment is (https://github.com/Shopify/shopify_api/blob/master/lib/shopify_api/resources/recurring_application_charge.rb):
module ShopifyAPI
class RecurringApplicationCharge < Base
undef_method :test
class << self
def current
(all || []).find { |c| c.status == 'active' }
end
[:pending, :cancelled, :accepted, :declined].each do |status|
define_method(status) { (all || []).select { |c| c.status == status.to_s } }
end
end
def usage_charges
UsageCharge.find(:all, params: { recurring_application_charge_id: id })
end
def cancel
load_attributes_from_response(self.destroy)
end
def activate
load_attributes_from_response(post(:activate))
end
def customize(customize_recurring_app_charge_params = {})
load_attributes_from_response(put(:customize, recurring_application_charge: customize_recurring_app_charge_params ))
end
end
end
Disclaimer: I've never coded in ruby nor is my app built in ruby, but this is the only example I could find, other were just carbon copies of the official test app.
So as far as I undrestand this method just checks the API for an active reccuring charge before issuing another reccuring charge call.
So If I change the plan "name" or "price" nothing is going to happen because there's an existing 'active' recurring charge (the check is done before the call to create a new reccuring plan).
So I don't get it... how can I make this work?
Also what happens to the current test users (they also have a valid 'reccuring test' charge), what about trial users, after trial expiration... does Shopify delete the 'active trial' reccuring plan?
Thank you for all your answers!
I've also posted this on the shopify forums: https://ecommerce.shopify.com/c/shopify-apis-and-technology/t/reccuring-charge-change-activation-402080
Just delete the active charge with the test or trial status, and issue the new one. Simple. It will replace the old one when the merchant chooses to accept the new charge, which should be offered to them.

How to create test account with PayPal Payments Pro (Use to represent yourself as a merchant using Pro) option selected in sandbox?

I am unable to create Paypal sandbox test account with option PayPal Payments Pro (Use to represent yourself as a merchant using Pro). I selected the option during test account creation but when I viewed the details of that account, then it displayed
Account Type : Seller (Use to represent yourself as the merchant).
Please help me as I am unable to do credit card payment integration using sandbox as it is showing
error :
Array
(
[TIMESTAMP] => 2013-02-06T10:40:57Z
[CORRELATIONID] => 2732f8af3ec70
[ACK] => Failure
[VERSION] => 85.0
[BUILD] => 5060305
[L_ERRORCODE0] => 10501
[L_SHORTMESSAGE0] => Invalid Configuration
[L_LONGMESSAGE0] => This transaction cannot be processed due to an invalid merchant configuration.
[L_SEVERITYCODE0] => Error
[AMT] => 100.00
[CURRENCYCODE] => USD
)
Thanks in advance.
The API credentials in the Sandbox environment uses the default buyer account you have. You need to make sure to use the “payments pro” option when you create a buyer account in the sandbox environment. You’ll then see a new set of API credentials under API credentials…
Steps below:
Go to the link https://developer.paypal.com/us/cgi-bin/devscr?cmd=_sandbox-acct-session and login with your sandbox credentials
And click on the link Preconfigured which will take you to https://developer.paypal.com/us/cgi-bin/devscr?cmd=_create-account-session
From the options select Website Payments Pro (Use to represent yourself as a merchant using Pro) and create a Test Account and use these details for sandbox

how to process incoming emails and update them into the database table in ruby on rails 3

I'm trying to set up my RoR 3 application to receive emails and then process those emails and update them into the database table called product_comments.
In my application, I have products_controller. Admin can approve or disapprove the products. when the admin disapproves the product, admin adds a comment and that comment will be mailed to the artist, if artist replied to that mail, the product_comments table should be updated to store the replied comment and replied date.
Here is (part of) what I have in my products controller:
if #productcomment.save
ArtistProduct.where(:id=>params[:id]).update_all(:astatus=>'disapproved', :status=>'disapproved')
UserMailer.comment_email( #productcomment).deliver
end
When users add a comment, the admin receives an email. When admins add a comment, users receive an email. (This is already functioning.)
I'm using Cloudmailin to help me receive incoming mail. I've set up the Cloudmailin address to point to http://myapp.com/incoming.
I am not getting how to integrate Cloudmailin to my application. Please help me.
UPDATE
I have just created incoming controller and my incoming controller looks like:
require 'mail'
def create
#comment = ProductComment.find_by_token(params[:to].split('#')[0])
ProductComment.update(:id=>#comment.id,{:reply => params[:plain], :rfrom=>params[:from], :replieddate=>params[:date]})
render :text => 'success', :status => 200
end
My question is how i will get the comment id? While sending an email i want specify comment id or not? if want to specify that id where i want to specify. I have created one account in Cloudmailin is that enough for process the incoming mail or i need to follow any other steps to receive the mail to my application? that is any server setting should be done or what. I am getting any thing. Please help.
Now am sending an email like:
mail(:to => #user.email, :subject => "Edit Your Product")
and i Have set the from as default and it looks like:
default from: "abc#xyz.com"
This is the admin email address.
Please help me.
You can use mailman.
The user guide has an example that does just what you are asking for.