Hi,

Looking to use this module along with commerce_recurring v2 but have noticed the paypal module does not have the card on file charge feature implemented. I'd really like to use this feature.

Cheers

CommentFileSizeAuthor
#75 1968592-n55-proper-n75.patch293.58 KBhanoii
#73 1968592-n55-proper.patch19.95 KBhanoii
#11 1968592-start_to_integrate_abandoned-11.patch18.53 KBtmsimont
#13 commerce_paypal-restapi_vault_integration-1968592-13.patch26.17 KBKazanir
#15 commerce_paypal-restapi_vault_integration-1968592-15.patch27.13 KBKazanir
#32 commerce_paypal-restapi_vault_integration-update-method-corrected.patch311.19 KBjmary
#43 commerce_paypal-restapi_vault_integration-update-method-patch-against-7.x-dev.patch282.94 KBjmary
#43 commerce_paypal-restapi_vault_integration-update-method-patch-against-7.x-2.3.patch282.94 KBjmary
#44 commerce_paypal-restapi_vault_integration-1968592-44.patch18.82 KBjmary
#50 commerce_paypal-restapi_vault_integration-update-method-patch-against-7.x-dev-50.patch284.93 KBTimRutherford
#50 interdiff-1968592-43-50.txt12.96 KBTimRutherford
#51 interdiff-1968592-43-51.txt22.72 KBTimRutherford
#51 commerce_paypal-restapi_vault_integration-update-method-patch-against-7.x-dev-51.patch293.1 KBTimRutherford
#52 interdiff-1968592-43-52.txt30.12 KBb_sharpe
#52 commerce_paypal-restapi_vault_integration-update-method-patch-against-7.x-dev-52.patch293.36 KBb_sharpe
#55 commerce_paypal-restapi_vault_integration-update-method-patch-against-7.x-dev-55.patch.txt294.25 KBmanishs
#61 commerce_paypal-restapi_vault_integration-update-method-patch-against-7.x-dev-61.patch39.44 KBtrrroy
#62 commerce_paypal-restapi_vault_integration-update-method-patch-against-7.x-dev-62.patch.txt41.5 KBtrrroy
#64 commerce_paypal-restapi_vault_integration-update-method-patch-against-7.x-dev-64.patch42.59 KBtrrroy
#65 commerce_paypal-restapi_vault_integration-update-method-patch-against-7.x-dev-65.patch42.75 KBtrrroy
#67 interdiff_67.patch.txt1.59 KBtrrroy
#67 commerce_paypal-restapi_vault_integration-update-method-patch-against-7.x-dev-67.patch43.08 KBtrrroy

Comments

dinofile’s picture

I second this. At the very least, it would be nice to have some feedback from the developers on their intentions/opinions/progress on this.

torgospizza’s picture

I have noticed in Commerce PayPal that there is a checkbox for creating Reference Transactions to facilitate this. Perhaps more work needs to be done to further extend that into Card on File functionality.

For example, with Woot.com, you can enter a billing agreement with PayPal, and then on your next checkout, you simply select the PayPal option and enter your PayPal password. You never have to "confirm" on the PayPal site again. Would love to be able to offer our customers that same functionality.

rszrama’s picture

Title: Card on File » Card on File / Recurring module integration

Updating this issue to close out the related one for Recurring.

Re: billing agreements, we do support reference transactions through them, but right now they aren't yet tied into CoF or Recurring. There's the propensity for it and support for it from an API standpoint, but it remains to be integrated into the other modules.

I'll be leaving this issue open to track it as an open feature request.

SeanBannister’s picture

rszrama’s picture

Not sure, to be honest. It depends on if that issue was intended to refer to PayPal's own recurring solution.

tmsimont’s picture

Not a duplicate. #1126836: Add support for PayPal's Subscriptions and Recurring Billing features is about "subscription" whereas this issue is about integration with Card on File.

Although both pertain to billing a user on a regular interval, this issue is about billing automatically with CoF/Recurring while the other issue is more about billing regularly to keep a "subscription" alive. The latter does not require an automatic billing process where the former is solely that.

It seems the authorize.net payment method module currently provides CoF support.

I've looked around and I don't think any work has been done for PayPal WPP. Can anyone let me know if there's a sandbox out there or a patch?

tmsimont’s picture

OK so this is the current situation as far as I can tell:

Commerce Card on File works by storing a reference to a credit card. It can then use that reference to retrieve that credit card and create and charge new orders.

Commerce Recurring uses cron and rules to allow products to trigger new charges via Card on File at regular intervals, which are configured by the fields provided by Commerce Recurring.

This works great with Authorize.net, but PayPal's method of card handling makes this difficult.

PayPal currently has 2 different API's. I have been reading a lot about PayPal's products, and exactly where the line gets drawn here is extremely confusing. Apparently, what was once known as PayPal WPP, and is now sometimes referred to as PayPal Payments Pro, doesn't support the new "REST API" -- it only supports the "Classic API"

As an aside, I have no idea what is going on with PayPal these days. Their sandbox has changed drastically and is totally buggy, and their product references are inconsistent and confusing. I don't understand when I can use one API over the other, and trying to understand what type of account is required for certain services is an absolute nightmare. I've been trying to reach their support and I've been waiting for weeks to get a clear answer on how their services are supposed to work with the account level I have...

Anyway.. As far as I can tell there are 3 different PayPal "services" that would support a recurring billing method, but exactly what kind of account is required for each is an absolute mystery.

PayPal Vault API

"REST API" based method
https://developer.paypal.com/webapps/developer/docs/integration/direct/s...
It looks like this would be ideal for integration with Commerce Card on File and Commerce Recurring.
This API allows you store a CC reference, call it back up and make new transactions, and update/delete.

However, I have Paypal Payments Pro, and integrated it into my site with Commerce Paypal. After explaining my integration to an "Integration Engineer" this is what I was told:

Regarding the recurring billing feature and the Vault API, it will not work. Vault is our new implementation with REST APIs but since your original integration is using our Classic PayPal APIs, the vault will not work.

I don't understand what that means and of course they have yet to respond with clarification.. but apparently the Vault API doesn't work with WPP (or PPP)

Reference Transactions

"Classic API" method
https://developer.paypal.com/webapps/developer/docs/classic/express-chec...
It seems the "Classic API" supports this method of "Card on FIle" in which a transaction is created, and a reference to that transaction can be stored. This would also work the Commerce Card on File because you could store that reference as a card.

However, this doesn't work if you want your recurring interval to be greater than or equal to 365 days, or if you need the amount to differ from the original transaction and subsequent recurring transactions.

Recurring Billing Profiles

"Classic API" method
https://www.paypalobjects.com/webstatic/en_US/developer/docs/pdf/pp_payf...
In this scenario, all the recurring logic (like what Commerce Recurring handles) is handled on PayPal's server. This would not work with Commerce Card on File because the card reference is never recalled in Drupal. The "recurring profile" is configured with an initial transaction, and settings like amount and interval are sent to PayPal. PayPal then handles the recurring charges, and sends out IPN notifications when charges are made. The profile can be managed by reference, but there's no way that this kind of system would ever make sense to integrate to Commerce Card on File or Commerce Recurring.

It looks like this module integrates with this recurring profile method: https://drupal.org/project/commerce_sp_paypal but it's dependent on a "Subscription product" type... That's unfortunately not nearly as flexible as the features provided in Commerce Recurring and Card on File...

Summary

It seems that the best PayPal option here is the "Vault API"

I'd started to write a patch for commerce_paypal_wpp, but a week after contacting PayPal about this I was told that I can't use the REST API with my WPP account. I am still waiting for clarification about why that is, and as long as that's out, there's really no good way to get this integrated with Card on File...

SeanBannister’s picture

Thanks for that great summary, I'm really interested to hear how you go with this.

tmsimont’s picture

OK so I got clarification on the Vault API bit --

It's totally OK to use the Vault API with WPP, but the problem that it presents is that the current WPP module is written with the Classic API. (or is it not?)

I don't think it would cause a problem to use the two API's separately, but the calls to PayPal made during checkout with a new card that is to be saved would be more streamlined if you could save that card while making the initial charge. The only way to make that happen would be to use the REST API for both card saving and normal WPP checkout. This would require some refactoring of the WPP module. Unless, it's using the new REST API (I haven't looked yet)

I might have to abandon this whole project, however, because I recently realized that using the PayPal WPP module puts you into the PCI SAQ C category of PCI compliance requirements.. So I don't know if I'll continue if we are not SAQ C

rszrama’s picture

The current WPP is using the classic API, but I wouldn't be opposed to converting it to use the REST API if necessary. I'm aware these are newly available, so I expected we'd get to using them sooner or later. What I'd wonder is can we make the change in API without requiring an update path? In other words, would we be able to leave the settings form as is and just change how we communicate with PayPal?

tmsimont’s picture

The API authentication works with the same configuration, and there's still a sandbox/live mode. So I think the upgrade would work fine without needing to write any update functions.

I'm going to abandon this, however, because I can't use PayPal and be PCI Compliant with the SAQ-A guidelines. I am going to use Braintree.

I did a little bit of work on this before giving up.. One thing I found frustrating is that to use the REST API SDK that PayPal offers, you need to use Composer...

I started patching commerce_paypal to use composer, and threw together some basic code for this... but like I said, I had to bail out..

Here's a patch anyway that might get you started on using the Recurring API, but it's basically crap at this point... still needs a lot of love.. I started by copying in the necessary function from commerce_authnet and started writing in some examples from PayPal API.

I also added in composer.. which may be a terrible idea.. so take this or leave it... (I did not add in the dependency to the info file, but this code would require https://drupal.org/project/composer_manager)

Sorry I can't be more helpful but this whole experience has made me want to never use PayPal again.. I like the looks of Braintree so far for quite a few reasons.

jsibley’s picture

Issue summary: View changes

Any progress? This seems like yet another dead end, so far, in finding a working, supported solution for subscriptions using Paypal....

Kazanir’s picture

I took a crack at this over the weekend after chatting with yaworsk in IRC. The attached patch is rough and mostly untested still. It took four things to get this off the ground:

1. Revamped the commerce_paypal API request function to be able to take parameters of any kind, not just the existing name-value-pairs style. This changes the $nvp variable to $params and adds a bunch of is-this-a-REST-API-request logic. (It looks for a [restapi] key in the $params array to determine this.) This means that the existing modules can go right on using their current calls and switch over to the REST API as they get refactored. I didn't use the SDK at all -- it seemed like overkill and I didn't want to be tied to what they have or haven't implemented yet -- and the SDK is missing some key calls.

2. Extended the WPP module's payment method settings form to include a spot for REST API credentials, which are different than the Classic (NVP) API being used right now. Other modules will need to do the same if they want to switch. The settings keys are restapi_clientid and restapi_secret.

3. Adds the commerce_paypal_vault module which contains the relevant callbacks for commerce_cardonfile. This module also hooks the WPP payment method info to add those callbacks to it and provides an additional form submit function (which maybe should be in the WPP module directly, I couldn't decide.) This part probably wants custom form callbacks built rather than using the cardonfile defaults. Additionally, the "update" callback doesn't work yet because PayPal's developer documentation on their REST PATCH method is non-existent.

4. Modifies the commerce_wpp payment form submit functions to check if a cardonfile card is being used to pay (and reroutes the payment creation appropriately) and also adds the functionality to add a new card if the cardonfile checkbox is checked. (It turns out that the Card On File module doesn't automatically use its callbacks to create or charge stored cards through the checkout process -- the implementing module has to alter its own form submit process to do both of these things. The callbacks above are for direct creation/deletion/modification.) This is still pretty untested.

Please feel free to review and test it out; I'll probably have a bunch of revisions sometime this week as well.

robertdouglass’s picture

@Kazanir, some feedback that I got from Ryan. He's in the middle of a code sprint, so wasn't able to study the patch, but he feels the approach is wrong. Perhaps you shouldn't try to make the same function serve both types of PayPal's APIs, but rather just add an additional function to serve REST requests vs. their classic API requests. The way it's implemented now makes that one function unnecessarily complex.

Kazanir’s picture

Yeah that's a much better idea. I had initially started that way but wanted to try to re-use what parts of the existing function I could -- unfortunately there wasn't that much there to re-use and it got quite unwieldy.

I have refactored that part and fixed/added a bunch of things.

Unfortunately, due to the way Card on File is written, the Views operations links handler for the Card on File entity won't provide any operations links until we can implement the update callback. (This is because the operations links rely on menu_contextual_links for a page which has its access callback set to check access to the un-implemented update callback, and that page naturally comes back 403! So no links.) I'm waiting on a response from PayPal Developer Support on their undocumented PATCH method. I believe at this point I've tested everything except a recurring-driven charge of a stored card which I just did through checkout.

I also had to add in the standard "enabled card on file" checkbox to the WPP settings form which I had forgotten. At some point when I find more time I'll write the API docs for Card on File to go along with this; it has been a useful learning experience.

maxplus’s picture

Great work so far.
I'm not a developer so I cannot help to develop but I can help to test.
The only thing is that I'm working with WPS right now,... (I don't think I can use other Paypal methods here in Belgium)

Adnan Dulep’s picture

Hello Kazanir,

I have notice you contacted PayPal Developer Support regarding issue with missing operations links
when Card on File is combined with PayPal.

Did you received response from PayPal Developer Support and could you share info regarding operations links issue.
I am interested in resolving this issue and I would appreciate it if you have some suggestion or useful information that
could help me to resolve this problem.

adshill’s picture

We could have some resources for this as its high time paypal worked with recurring framework and CoF! Does anyone have an estimate in time, and are the starting points listed above the right direction. Let us know how we could progress to try and get this out the door and we'll do our best to get our client to fund it.

Kazanir’s picture

Adnan and adshill,

I'm going to try to work on this today. I didn't get a useful response from Paypal dev support so I will work on establishing a connection via our corporate contacts. I don't think sponsorship is necessary at this point -- this is pretty much done as it stands and just needs the PATCH method implemented (for the edit/update form) and a lot of testing once it is committed to the dev branch. Stay tuned!

nedjo’s picture

Thanks for your work here. It looks like a good start, but also underlines the complexity of the task. As usual when integrating with an external REST server, the patch is difficult to evaluate without a detailed knowledge of the Paypal REST API. What are valid request parameters? What are possible responses? Since we're only integrating with a subset of the API, we end up coding seemingly arbitrary responses that are difficult to debug. That said, the patch includes a lot of helpful inline comments.

Some comments from a quick scan of the code. Some of this relates to code that's merely been copied from existing functions elsewhere in the module.

  1. +++ b/commerce_paypal.module
    @@ -392,7 +392,243 @@ function commerce_paypal_api_request($payment_method, $nvp = array(), $order = N
    + *   Parameters for this API request. This array is encoded into the JSON ¶
    

    Extra whitespace at end of line (here and many other places).

  2. +++ b/commerce_paypal.module
    @@ -392,7 +392,243 @@ function commerce_paypal_api_request($payment_method, $nvp = array(), $order = N
    +    watchdog('commerce_paypal', 'PayPal REST API request to @url: !param', array('@url' => $url, '!param' => '<pre>' . check_plain(print_r(array('Rest API' => $rest,'Params' => $log_params), TRUE)) . '</pre>'), WATCHDOG_DEBUG);
    

    Since this output is repeated below, it might warrant a helper function, e.g., _commerce_paypal_rest_api_request_debug().

  3. +++ b/modules/vault/commerce_paypal_vault.module
    @@ -0,0 +1,245 @@
    +    return FALSE;
    +    drupal_set_message(t('This card was not able to be added. Please contact the site administrator for additional information.'), 'error');  ¶
    

    drupal_set_message() won't be called as it comes after the return call.

  4. +++ b/modules/wpp/commerce_paypal_wpp.module
    @@ -173,6 +185,23 @@ function commerce_paypal_wpp_settings_form($settings = array()) {
    +  if (module_exists('commerce_cardonfile') && module_exists('commerce_paypal_vault')) {
    

    commerce_cardonfile is a dependency of commerce_paypal_vault, so no need to test for both.

  5. +++ b/modules/wpp/commerce_paypal_wpp.module
    @@ -173,6 +185,23 @@ function commerce_paypal_wpp_settings_form($settings = array()) {
    +      '#markup' => t('To enable Card on File functionality download and install the Commerce Card on File and Commerce PayPal Vault modules.'),
    

    Commerce Paypal Vault is not a separate download.

  6. +++ b/modules/wpp/commerce_paypal_wpp.module
    @@ -448,10 +488,85 @@ function commerce_paypal_wpp_submit_form_submit($payment_method, $pane_form, $pa
    +  dpm(array('pm' => $payment_method, 'pv' => $pane_values));
    

    Debugging call.

  7. +++ b/modules/wpp/commerce_paypal_wpp.module
    @@ -448,10 +488,85 @@ function commerce_paypal_wpp_submit_form_submit($payment_method, $pane_form, $pa
    +    dpm($response);
    

    Debugging call.

  8. +++ b/commerce_paypal.module
    @@ -392,7 +392,243 @@ function commerce_paypal_api_request($payment_method, $nvp = array(), $order = N
    +  drupal_alter('commerce_paypal_rest_api_request', $params, $order, $payment_method);
    

    Why does the alter come at this point of the process, after the URL has been calculated? Do we want to prevent altering of the URL components? Why?

  9. +++ b/commerce_paypal.module
    @@ -392,7 +392,243 @@ function commerce_paypal_api_request($payment_method, $nvp = array(), $order = N
    +  // Setup the cURL request.
    +  $ch = curl_init();
    +  ¶
    +  // Set up the REST API info: JSON request/headers and OAuth token.
    +  curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $rest['method']);
    +  curl_setopt($ch, CURLOPT_POSTFIELDS, $rest_json);
    +  curl_setopt($ch, CURLOPT_HEADER, 1);
    +  curl_setopt($ch, CURLOPT_HTTPHEADER, array(
    +    'Content-Type: application/json', ¶
    +    'Content-Length: ' . strlen($rest_json),
    +    'Authorization: Bearer ' . $rest['token'],
    +  ));
    +  curl_setopt($ch, CURLOPT_URL, $url);
    +  curl_setopt($ch, CURLOPT_VERBOSE, 0);
    +  curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    +  curl_setopt($ch, CURLOPT_NOPROGRESS, 1);
    +  curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 0);
    +  curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 1);
    +
    +  // Commerce PayPal requires SSL peer verification, which may prevent out of
    +  // date servers from successfully processing API requests. If you get an error
    +  // related to peer verification, you may need to download the CA certificate
    +  // bundle file from http://curl.haxx.se/docs/caextract.html, place it in a
    +  // safe location on your web server, and update your settings.php to set the
    +  // commerce_paypal_cacert variable to contain the absolute path of the file.
    +  // Alternately, you may be able to update your php.ini to point to the file
    +  // with the curl.cainfo setting.
    +  if (variable_get('commerce_paypal_cacert', FALSE)) {
    +    curl_setopt($ch, CURLOPT_CAINFO, variable_get('commerce_paypal_cacert', ''));
    +  }
    +
    +  $result = curl_exec($ch);
    +
    +  // Log any errors to the watchdog.
    +  if ($error = curl_error($ch)) {
    +    watchdog('commerce_paypal', 'cURL error: @error', array('@error' => $error), WATCHDOG_ERROR);
    +    return FALSE;
    +  }
    +  curl_close($ch);
    

    While I agree that it makes sense to have this new API call in a separate function, much of this is duplicated from commerce_paypal_api_request() and so should be pulled into a helper function, e.g., _commerce_paypal_curl_request().

  10. +++ b/commerce_paypal.module
    @@ -392,7 +392,243 @@ function commerce_paypal_api_request($payment_method, $nvp = array(), $order = N
    +  // with the curl.cainfo setting.
    

    This is useful documentation, but is aimed at site builders rather than developers and so would better go in a more visible place, like a README file.

Adnan Dulep’s picture

Hello Kazanir,

Is there any news/progress regarding issue with edit/update form functions?

zmove’s picture

+1 to this

janvonmulert’s picture

Hi Kazanir, Any updates? Still waiting to hear from Paypal? We need this bad down here in New Zealand.... None of our local payment gateway modules integrate with card on file :(

kopeboy’s picture

I have gone trough the Paypal nightmare as well, still haven't figured out.
Additional problem is that everywhere outside Australia, US, UK you cannot use Paypal Payflow /link (new API right?) but only WPS or Paypal Pro.

Any update so we can finally add some subscription / automatic billing functionality??

In the meantime we have looked at the only other method available in Europe (Italy) integrated with Card On File, which is PAYMILL.
Activating a PAYMILL account for recurring billing? Even worse nightmare than Paypal!!

This is what they reply after a registration on their site (with already around 100 fields filled, including personal data of every shareholder over 20% on the company):

Thank you for choosing Paymil.

My name is Maria and I was assigned as your personal contract manager. I will take care of your activation process to have credit card payments on your website.

In order to issue a contract with the acquirer that suits your business model better I will need some additional information.

I have summarized this information for you below:

Busines model: on your application you stated that you are seelling Advertisement and visibility services for vendors of the wedding industry. However, this is not reflected on the terms of the site. Do you have a separate terms or portal for the people that want to advertise on your site ?

- Delivery time: are you going to offer subscriptions to advertise on your site ? if you are this ones going to be monthly / yearly and automatically renewed ?

- Subscriptions information: if you offer subscriptions as stated on your application, please notice that this information needs to be clearly stated on the paying / buying page and also on the terms and conditions.

- Cancellation: Please add to your website information concerning the cancelation of any purchase of your product/service

- Refund policy: Please explain on your website the necesary steps a customer must go through in order to receive a refund after cancelling service or returning a product.

- Language consistency: On the test website, the english language is not working on the whole website, is there any plan to also translate the articles of the website ?

- Imprint: please add on your contact page, the name, address and phone number of the company.

- Beneficial owners: On our research, we noticed that the company is owns in 4 equal parts by 4 persons (Mr. XXXX, Mr. YYYY, Mr. ZZZZ and Mr. QQQQ). Please add your data to the section 6 in Merchant Center , where is says activation form (Significant shareholders) as the four persons stated are beneficial owners with vote rights and 25 % of the shares.

- Card brands: On your application you selected additional cards like Amex, Diners, JCB and CUP. Would you be able to provide an estimation of the monthly revenue that you expect on these cards? Two of the cards you have selected, CUP and JCB, only work for the Chinese and Japanese markets. As a result, these brands take longer to approve, which might delay your account activation.

- VAT ID country code: is your vat id european ? It should start with IT . Otherwise, please let me know.

- Issuing of invoices: Please add to your website information regarding the invoicing of purchases from your website. Please state clearly when and how (email, letter etc.) your customers are informed of any purchase.

- Passport: does all the beneficial owners hold a valida passport ?

Please note, that your website needs to be fully compliant before we can submit it to the acquirer for the clearance process. Therefore, I am attaching a document, with the website requirerments.

If you have any further question regarding these points, please feel free to contact me at your first convenience,

Thank you and kind regards,

WTF is wrong with them?? Do they really need to know all those things and tell me what to put on my website to accept payments?! What if I want to test them before paying for writing a policy? Anyway...

Summarizing: PLEASE HELP THE COMMUNITY (outside US) WITH RECURRING PAYMENTS
This is the only issue I have with Drupal Commerce, which otherwise is perfect (I love you all)!

nyumbani_yangu’s picture

Any update on getting paypal recurring payment working with card on file and/or commerce license billing?

+1 in need for this type of support

adshill’s picture

Our client is still willing to get involved in contributing to make this happen and therefore we could devote resources but would prefer to do it in co-operation. Is anyone available to work through this with our developer and does anyone have an accurate idea of what it may take?

Kazanir’s picture

Adshill: This patch is mergeable now, but lacks an edit form. All that we need to do beyond that is determine the nature of Paypal's PATCH method (which is probably very similar to the POST for creating a new Vault entry) and then add that to an edit form. Beep me on #drupal-commerce tomorrow (or, more likely, Tuesday) and we can take a look at finishing this up.

capfive’s picture

How did you guys go?

Would be great to get this integrated to have as a secondary payment method for membership style sites

Keep up the good work!

daniel wentsch’s picture

Bumping in as I feel a bit desperate about implementing recurring payment. Any progress on this?

torgospizza’s picture

Also looking into this. I would rather not "force" our users to use a card on file (though that is preferred) and would like to utilize PayPal EC as a payment method option for subscriptions. What's the status of this patch?

jmary’s picture

@Kazanir : I'm definitely willing to help on that. In order to get fast, I'm willing to have a skype call with you so that I can quickly get pointed to the keypoint to terminate this. I have the next 10 days to dedicate on that, most of my day, for in the end provide a solution that all commerce_paypal users will be happy to get.

I'm located in Hong Kong (GMT +8) but I'm French and speaks fluent english.

Better to skype me : #takaware

jmary’s picture

Here is an update of the patch #15 implementing the PATCH method to update a credit card record.
This patch applies against the version 2.3 and not the dev.

I couldn't test it at all, because I cannot have REST API credentials yet. I'm not sure yet, but the REST API to do such things is only for US. As I am in Hong Hong, I might have to recode everything using the NVP / SOAP.

Please not that you need to download : https://raw.githubusercontent.com/bagder/ca-bundle/master/ca-bundle.crt

Place it anywhere in your filesystem and modify your settings.php at adding anywhere :

$conf['commerce_paypal_cacert'] = '/path/to/the/file/ca-bundle.crt';

Of course /path/to/the/file needs to reflect your actual directory.

Then go to enable the commerce_paypal_vault module, and also to edit and review the settings of the WPP method.

jmary’s picture

Status: Active » Needs work
colan’s picture

How does this work relate to / compare with the code over at Commerce License Billing Paypal?

The corresponding issue in that queue is #2683729: Comparison with Card on File / Recurring module integration?

jmary’s picture

After testing I can say that the updated patch on #32 seems to work, at least in my sandbox.
Please test at following the instructions I've provided.

Collins405’s picture

I installed everything as #32 describes, but I get the following error in watchdog... cURL error: error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure

companyguy’s picture

jmary, I followed you're instructions for this patch and I'm still having troubles. I'm getting the following error

cURL error: error setting certificate verify locations: CAfile: /ca-bundle.crt CApath: /etc/ssl/certs

I've got the ca-bundle.crt file in the root directory, but the error looks to me like it can't find it. Here's what my php line looks like -

$conf['commerce_paypal_cacert'] = '/ca-bundle.crt';

I've tried changing the path to multiple places in my file system (/sites/default/files, /sites/default/private/files, etc...) and droping the file in those places but the error persists. Where did you put the file? Any ideas?

Thanks

Collins405’s picture

I put the cert in the root folder, and did this without the slash....

$conf['commerce_paypal_cacert'] = 'ca-bundle.crt';

And it worked.
Still havent got anywhere with this error though...

cURL error: error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure

jmary’s picture

#companyguy : I put the absolute path to the crt files, eg. /var/www/drupal/ca-budle.crt

#Collins405 : I haven't met the handshake failure error yet.

cmarcera’s picture

In my attempts to get #32 working, I attempted to submit a payment for $0.10 recurring product, but the data submitted to PayPal does not retain the charge amount:

PayPal API request to https://api-3t.paypal.com/nvp:

Array
(
    [METHOD] => DoDirectPayment
    [PAYMENTACTION] => Sale
    [NOTIFYURL] => https://dev.mysite.com/commerce_paypal/ipn/paypal_wpp%7Ccommerce_payment_paypal_wpp
    [BUTTONSOURCE] => CommerceGuys_Cart_PPP
    [CREDITCARDTYPE] => Visa
    [ACCT] => XXXXXXXXXXXX****
    [EXPDATE] => ******
    [AMT] => 0.00
    [CURRENCYCODE] => USD
    [CVV2] => XXX
    [INVNUM] => 6-1462396805
    [CUSTOM] => Order 6
    [DESC] => 1x TESTSUB-24HR-AR
    [EMAIL] => myemail@gmail.com
    [IPADDRESS] => ***.***.***.***
    [FIRSTNAME] => *********
    [LASTNAME] => *********
    [STREET] => *** ********* **
    [STREET2] => 
    [CITY] => *******
    [STATE] => **
    [COUNTRYCODE] => US
    [ZIP] => ******
    [USER] => *********.*********.****
    [PWD] => XXXXXXXXXXXXXXXX
    [SIGNATURE] => XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    [VERSION] => 76.0
)

In addition, when I disabled Devel, I got the following error in my error log:

PHP Fatal error: Call to undefined function dpm() in /var/www/html/sites/all/modules/commerce_paypal/modules/wpp/commerce_paypal_wpp.module on line 493, referer: https://dev.mysite.com/checkout/6/review

Not sure if something needs to be written in the to check if Devel is enabled or not.

jmary’s picture

Well, regarding the dpm issue, it is likely that I forgot to remove it.
You can remove any dpm call in the code.

Concerning the amount of 0.10, please try with an integer.
I faced some issues with wpp dividing the sums by 100. Proceed tests into paypal sandbox to avoid charges.

thejacer87’s picture

patch #32 is not applying to either branches, 7.x-2.3 or 7.x-2.x-dev. the patch deletes the commerce_paypal.module file, which I doubt is intended.

any help here would be great.

jmary’s picture

I have removed the dirty dpm calls which were left.

Here is a patch against dev version and against 2.3

From inside the commerce_paypal directory apply with :

patch -p1 < /path/to/where/you/stored/it.patch

I have tested that patch :

ju@ju-Latitude-E5540 /tmp $ drush dl commerce_paypal-7.x
Project commerce_paypal (7.x-2.3) downloaded to /tmp/commerce_paypal.[success]
Project commerce_paypal contains 5 modules: commerce_payflow, commerce_paypal_wpp, commerce_paypal_ec, commerce_paypal_wps, commerce_paypal.
ju@ju-Latitude-E5540 /tmp $ cd commerce_paypal/
ju@ju-Latitude-E5540 /tmp/commerce_paypal $ patch -p1 < ../commerce_paypal-restapi_vault_integration-update-method-patch-against-7.x-2.3.patch
patching file commerce_paypal.module
patching file modules/vault/certs/ca-bundle.crt
patching file modules/vault/commerce_paypal_vault.info
patching file modules/vault/commerce_paypal_vault.module
patching file modules/wpp/commerce_paypal_wpp.module
jmary’s picture

Patch against dev, created with git.

mobilemelody’s picture

Thanks so much for everyone's work on this. It's been a huge help to me. (Unfortunately I didn't realize how difficult integrating PayPal would be before we committed to using it...)

I noticed that credit card numbers in the logged API requests were not getting masked. I think the issue is with the commerce_paypal_sanitize_param function, where $value should instead be $param?

function commerce_paypal_sanitize_param(&$param, $key) {
  switch ($key) {
    case 'number':
      $value = str_repeat('X', strlen($value) - 4) . substr($value, -4);
      break;
    case 'cvv2':
    case 'cvv':
      $value = str_repeat('X', strlen($value));
      break;
  }
}
thejacer87’s picture

@jmary just to be clear, should i be using the patch in #44 or #43? the patch in #44 is much smaller. But it seems like that is only because the patches in #43 have the certs. Which is the best one to continue with?

this was the output for applying the patch in #44 to dev:

jbennest: commerce_paypal $ patch -p1 < ~/patches/commerce_paypal-restapi_vault_integration-1968592-44.patch 
patching file commerce_paypal.module
patching file modules/wpp/commerce_paypal_wpp.module

only two files were change instead of the 5 from #43:

patching file commerce_paypal.module
patching file modules/vault/certs/ca-bundle.crt
patching file modules/vault/commerce_paypal_vault.info
patching file modules/vault/commerce_paypal_vault.module
patching file modules/wpp/commerce_paypal_wpp.module

is this correct? or do we need the changes to the vault stuff too?

jmary’s picture

#43 will give you less work and provides a "work out of the box" solution.
#44 will require you to install the certs manually. It is there to fit a cleaner policy which should consist in supplying the code and provide documentation about certificates installation.

That makes me realize that a patch providing at the same time a correct README.txt shall replace #44.

thejacer87’s picture

#44 is still missing the vault submodule as well... i applied the dev patch in 43 and will do some work on that

thejacer87’s picture

Just ran a bunch of tests. Applied the dev patch in #43.

Scenarios without errors:

  • Standard credit card purchase - did NOT save card for future use
  • Standard credit card purchase - saved card for future use
  • Purchased with the card saved from previous order - No errors in the paypal sandbox thus far
  • Purchased with the card added in account settings - Got Drupal errors noted below
  • Removed my card on file in my account settings page

Scenarios with errors:

  • Trying to edit my card on file (ie change exp date)

    from paypal:
     Request {
    	"body": {
    		"path": "/",
    		"value": {
    			"expire_year": "2017",
    			"type": "visa",
    			"payer_id": "user_1",
    			"expire_month": "05"
    		},
    		"op": "replace"
    	},
    	"header": {
    		"x-pp-ads-performed": "false",
    		"content-length": "113",
    		"x-pp-silover": "name\\u003dSANDBOX3.API.1\\u0026silo_version\\u003d1880\\u0026app\\u003dplatformapiserv\\u0026TIME\\u003d2407811159\\u0026HTTP_X_PP_AZ_LOCATOR\\u003d",
    		"x-slr-orig-script_uri": "https://api.sandbox.paypal.com/v1/vault/credit-card/CARD-77G617171G6267033K5EIEAQ",
    		"client-auth": "No cert",
    		"host": "api.sandbox.paypal.com",
    		"authorization": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxXqUi",
    		"accept": "*/*",
    		"x-pp-corrid": "4e3fb3bfef3f7",
    		"pp_remote_addr": "184.70.234.66",
    		"content-type": "application/json",
    		"x-pp-slingshot-targetapp": "platformapiserv"
    	},
    	"additional_properties": {},
    	"method": "PATCH"
    }
    Response {
    	"status": 400,
    	"duration_time": 30,
    	"body": {
    		"message": "Incoming JSON request does not map to API request",
    		"debug_id": "4e3fb3bfef3f7",
    		"information_link": "https://developer.paypal.com/docs/api/#MALFORMED_REQUEST",
    		"name": "MALFORMED_REQUEST"
    	},
    	"additional_properties": {},
    	"header": {
    		"Content-Length": "195",
    		"Content-Language": "*",
    		"CORRELATION-ID": "4e3fb3bfef3f7",
    		"Date": "Fri, 27 May 2016 17:31:59 GMT",
    		"Connection": "close",
    		"Paypal-Debug-Id": "4e3fb3bfef3f7",
    		"PROXY_SERVER_INFO": "host\\u003dslcsbplatformapiserv3001.slc.paypal.com;threadId\\u003d748",
    		"Content-Type": "application/json"
    	}
    }
  • When I added a card in my account settings.
    Drupal errors:
    Notice: Undefined variable: value in commerce_paypal_sanitize_param() (line 588 of /.../sites/all/modules/commerce_paypal/commerce_paypal.module).
    Warning: str_repeat(): Second argument has to be greater than or equal to 0 in commerce_paypal_sanitize_param() (line 588 of /.../sites/all/modules/commerce_paypal/commerce_paypal.module).
    Notice: Undefined variable: value in commerce_paypal_sanitize_param() (line 588 of /.../sites/all/modules/commerce_paypal/commerce_paypal.module).
TimRutherford’s picture

Hey guys, good work so far!

I started working on patch #43 and made some good progress.

I figured out the format for update calls and fixed various other bugs. Almost everything seems to be working now.
One last issue is the 'capture' link not appearing for these Card on File payments if 'Authorization Only' is selected.

Ill keep working on the patch and back to you with any more progress made.

TimRutherford’s picture

Status: Needs work » Needs review
StatusFileSize
new22.72 KB
new293.1 KB

I got capture working for card on file payments now. To do so I had to create a new 'capture' link with a new form/form submit. I reused the form and form validation from the Commerce Paypal WPP module but had to re-do the submit handler to use the REST API.

Some next steps:
1. Possibly change the patch based on #47 feedback (removing the certs and adding a readme).
2. Reviews!

b_sharpe’s picture

Great work Tim!

- Add card via stored cards - working
- Edit card via stored cards - working
- Delete card via stored cards - working

- Add card via checkout - working
- Use card via checkout - working
- Select secondary card via checkout and set default - working

- Auth only - Capture via admin after - Working

Changes:
- Updated patch to be relative to module dir
- Added README
- Changed location of COF placement to be with card settings
- Fixed PHP warning if enabled after WPP
- Removed dependencies to other modules, and just added WPP

If we can get a quick review this should be RTBC :)

thejacer87’s picture

Status: Needs review » Reviewed & tested by the community

Works like a charm. Thanks paypal for making it so easy :)

jmary’s picture

Nice team work. Thanks to all contributors : tmsimont for initial patch, Kazanir for almost finished work, Thejacer87 for detailed bug report, TimRutherford and b-sharpe to have corrected remaining bugs and done some polishing, and myself (finished implementation of PATCH method) :-)

Good work guys.

manishs’s picture

There was one bug where the following error is given in PayPal API response when the amount is a decimal, not passed formatted to 2 decimal places, e.g. $1.10 is passed as 1.1. Attaching a patch with the fix for it over patch #52.

PayPal Vault card on file charge failed: transactions[0].amount.total -- Currency amount must be non-negative number and can optionally contain exactly two decimal places separated by '.', optional thousands separator ',', limited to seven digits before the decimal point.

Great work guys!

g33kg1rl’s picture

Which patches do I need to apply to get Card On File working with Commerce Paypal? #52 and #55?

spencerbrooks’s picture

@g33kg1rl: I was able to get things working properly in a PayPal sandbox environment with #55, for what it's worth.

manishs’s picture

Applying just #55 should be sufficient. It includes the previous changes including #52.

b_sharpe’s picture

Status: Reviewed & tested by the community » Needs work

Spoke with @rszrama and he is not willing to merge this in while we still have the certificates in the module (I agree this isn't the place for them).

If someone is willing to take this on, update the README on where to get the certs, and maybe cleanup the patch a little (Why are vault + card on file settings / actions in the wpp module?) we can get this merged in.

Otherwise I have this on my list, but that list is long :)

benjmarr’s picture

Is the patch in #55 just to apply to latest dev (nov-15)?

trrroy’s picture

Here's a new patch against the dev version. I did:

  • remove certs
  • update readme
  • clean-up of file

I did not make any changes to vault + card on file settings / actions in the wpp file. Those seem to wire together functionality for a couple modules so I'm not sure where would be better. I'm open to suggestions.

So far, I had a successful initial transaction go through my sandbox. I still need to test all the way through the recurring transactions.

trrroy’s picture

After a little more testing I have a few updates.

1) After my first tests, I moved to my code to another server with SSL enabled and ran in to some issues with Card on File data not being stored. This new development server was was behind a firewall refusing traffic from the outside world which prevented the retrieval of an API token from Paypal. The result was a successful initial payment but the retrieval of the remote card id for Card on File was failing. I added some error handling for this scenario and notes to the README file.

2) While troubleshooting #1, I found the 'chr' module works as an alternative to setting up the cert file and is easier to setup so I added this to the README too.

3) The Paypal Sandbox does not show CVV with the credit card information for an account so initially I did not have it enabled in the WPP settings but the module was still trying to send a blank value which caused error so I added handling to respect the switch in the rule. But then I found the transactions would not succeed without a CVV value so I added this to the Configuration information in the README. Using the Sandbox, any value for CVV will work.

trrroy’s picture

More testing has turned up a couple issues. Transactions are working intermittently for me. I keep seeing the cURL error "NSS: client certificate not found (nickname not specified)" and then the card isn't saved and the rest of the rules quit processing (Amazon ec2 with standard amazon linux). I found this message was coming from curl_error but the result for curl_errno = 0 so it seems like it's throwing a message but curl is completing successfully? With the change below in commerce_paypal.module (about line 574) then transactions are completing consistently. I have a subscription payment recurring every 10 minutes in the Paypal sandbox.

-  if ($error = curl_error($ch)) {
-    watchdog('commerce_paypal', 'cURL error in api request: @error', array('@error' => $error), WATCHDOG_ERROR);
+  $errno = curl_errno($ch);
+  if ($errno != 0) {
+    $error = curl_error($ch);
+    watchdog('commerce_paypal', 'API request for PayPal: cURL error number @errno: @error', array('@errno' => $errno,'@error' => $error), WATCHDOG_ERROR);

At this point, I'm confused on the need for the cert at all. As a test, I have cleared the commerce_paypal_rest_api_token, removed the $conf setting with the cert path and I disabled the chr module and it seems transactions are still working. Is it working because there is a valid SSL cert on my server?

trrroy’s picture

After lots more testing, it seems the cert file is not needed.

I moved the vault + card on file settings / actions out of the wpp file and into the vault module.

Another issue I came across using this with the commerce_discount module. Once I applied a discount, if the order amount went to $0 then the transaction would fail and the credit card info was not saved into the Vault. I added a fix to this patch so the card is saved to the Vault first and then if the amount is <= 0 then it logs the transaction and does not attempt a PayPal charge.

Also, my setup uses commerce_node_checkout. There was an error being thrown on any orders with any line items that were not commerce_node_checkout types. The patch for Non-product line items break rules integration fixes it.

trrroy’s picture

I made a couple mistakes when I moved the vault functions out of WPP and consolidated. They're fixed in this patch.

b_sharpe’s picture

Status: Needs work » Needs review

#65 applied and working for me, great work trrroy! Someone else want to give it a once over and get this RTBC?

trrroy’s picture

I found that the billing address collects a single "Full Name" field then the credit card transaction splits that to get first and last name to send with the card information. Without a last name the card will not save. This adds a message to the user and stops the checkout if the credit card profile does not save for future transactions. The error messaging to user is a little vague but details are written to watchdog.

celtech’s picture

I fully applied the patch from #67 but am not getting the option to Save Card on File when checking out using Paypal WPP.

trrroy’s picture

There are a couple steps for config in the README.txt for the vault module. Are these applied?

 * Configuration options are on the Payment Method for WPP
   /admin/config/workflow/rules/reaction/manage/commerce_payment_paypal_wpp

   1. Enter your client id and secret

   2. Choose to enable Card on File support
ibuildit’s picture

It's not working for me either, latest dev + #67

It's working fine, but I was looking in the wrong place, the checkbox is there in Website Payments Pro, and I had to activate the Paypal Vault module too.

TheWinkingSkeever’s picture

Trying to get this to work in 2018, I have errors showing NOT_IMPLEMENTED in watchdog whenever we try to process the Credit Card on File using patch #67. Upon searching PayPal Developer documentation:

"Important: The use of the PayPal REST /payments APIs to accept credit card payments is restricted. Instead, you can accept credit card payments with Braintree Direct."

Does this mean Card on File no longer works with the current patch (#67) or is there another way around this?

hanoii’s picture

StatusFileSize
new19.95 KB

IGNORE THIS PATCH unless need to apply #55, otherwise look for the latest one above. If you do need #55, see #75.

Sorry for this message, I got to review a project where #55 is being used. As part of the audit I am referencing this on a makefile so this is just a reroll of #55 properly formatted. Might soon review the newer ones.

hanoii’s picture

Hiding my previous patch so that it doesn't show as the most recent one.

hanoii’s picture

StatusFileSize
new293.58 KB

IGNORE THIS PATCH unless need to apply #55, otherwise look for the latest one above

Did something wrong on #73 with the patch, this is the proper re-roll.

hanoii’s picture

Hiding patch again.

tomtech’s picture

Status: Needs review » Closed (outdated)

Automatically closed because Drupal 7 security and bugfix support has ended as of 5 January 2025. If the issue verifiably applies to later versions, please reopen with details and update the version.