Giter Club home page Giter Club logo

killbill-paypal-express-plugin's Introduction

⚠️ Starting with Kill Bill 0.22, use the Braintree plugin instead ⚠️

killbill-paypal-express-plugin

Plugin to use PayPal Express Checkout as a gateway.

Release builds are available on Maven Central with coordinates org.kill-bill.billing.plugin.ruby:paypal-express-plugin.

A full end-to-end integration demo is available here.

Kill Bill compatibility

Plugin version Kill Bill version
2.x.y 0.14.z
4.x.y 0.16.z
5.x.y 0.18.z
6.x.y 0.20.z

Requirements

The plugin needs a database. The latest version of the schema can be found here.

Configuration

curl -v \
     -X POST \
     -u admin:password \
     -H 'X-Killbill-ApiKey: bob' \
     -H 'X-Killbill-ApiSecret: lazar' \
     -H 'X-Killbill-CreatedBy: admin' \
     -H 'Content-Type: text/plain' \
     -d ':paypal_express:
  :signature: "your-paypal-signature"
  :login: "your-username-facilitator.something.com"
  :password: "your-password"' \
     http://127.0.0.1:8080/1.0/kb/tenants/uploadPluginConfig/killbill-paypal-express

To go to production, create a paypal_express.yml configuration file under /var/tmp/bundles/plugins/ruby/killbill-paypal-express/x.y.z/ containing the following:

:paypal_express:
  :test: false

Usage

One-off payments

Create a payment method for the account:

curl -v \
     -X POST \
     -u admin:password \
     -H 'X-Killbill-ApiKey: bob' \
     -H 'X-Killbill-ApiSecret: lazar' \
     -H 'X-Killbill-CreatedBy: admin' \
     -H 'Content-Type: application/json' \
     -d '{
       "pluginName": "killbill-paypal-express",
       "pluginInfo": {}
     }' \
     "http://127.0.0.1:8080/1.0/kb/accounts/<ACCOUNT_ID>/paymentMethods?isDefault=true"

Without a pending payment

Generate the redirect URL using buildFormDescriptor (this will invoke SetExpressCheckout):

curl -v \
     -X POST \
     -u admin:password \
     -H 'X-Killbill-ApiKey: bob' \
     -H 'X-Killbill-ApiSecret: lazar' \
     -H 'X-Killbill-CreatedBy: admin' \
     -H 'Content-Type: application/json' \
     -d '{
       "formFields": [{
         "key": "amount",
         "value": 10
       },{
         "key": "currency",
         "value": "USD"
       }]
     }' \
     "http://127.0.0.1:8080/1.0/kb/paymentGateways/hosted/form/<ACCOUNT_ID>"

The customer should be redirected to the url specified in the formUrl entry of the response, e.g. https://www.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token=EC-20G53990M6953444J.

Once the customer comes back from the PayPal flow, trigger the payment:

curl -v \
     -X POST \
     -u admin:password \
     -H 'X-Killbill-ApiKey: bob' \
     -H 'X-Killbill-ApiSecret: lazar' \
     -H 'X-Killbill-CreatedBy: admin' \
     -H 'Content-Type: application/json' \
     -d '{
       "transactionType": "PURCHASE",
       "amount": "10",
       "currency": "USD"
     }' \
     "http://127.0.0.1:8080/1.0/kb/accounts/<ACCOUNT_ID>/payments"

With a pending payment

Generate the redirect URL using buildFormDescriptor (this will invoke SetExpressCheckout):

curl -v \
     -X POST \
     -u admin:password \
     -H 'X-Killbill-ApiKey: bob' \
     -H 'X-Killbill-ApiSecret: lazar' \
     -H 'X-Killbill-CreatedBy: admin' \
     -H 'Content-Type: application/json' \
     -d '{
       "formFields": [{
         "key": "amount",
         "value": 10
       },{
         "key": "currency",
         "value": "USD"
       }]
     }' \
     "http://127.0.0.1:8080/1.0/kb/paymentGateways/hosted/form/<ACCOUNT_ID>?pluginProperty=create_pending_payment=true"

The customer should be redirected to the url specified in the formUrl entry of the response, e.g. https://www.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token=EC-20G53990M6953444J.

Once the customer comes back from the PayPal flow, complete the payment (the payment id and external key are returned as part of the buildFormDescriptor call):

curl -v \
     -X PUT \
     -u admin:password \
     -H 'X-Killbill-ApiKey: bob' \
     -H 'X-Killbill-ApiSecret: lazar' \
     -H 'X-Killbill-CreatedBy: admin' \
     -H 'Content-Type: application/json' \
     "http://127.0.0.1:8080/1.0/kb/payments/<PAYMENT_ID>"

Recurring payments via a billing agreement ID (BAID)

Issue the following call to generate a Paypal token:

curl -v \
     -X POST \
     -u admin:password \
     -H 'X-Killbill-ApiKey: bob' \
     -H 'X-Killbill-ApiSecret: lazar' \
     -H 'X-Killbill-CreatedBy: admin' \
     -H 'Content-Type: application/json' \
     -d '{
       "kb_account_id": "13d26090-b8d7-11e2-9e96-0800200c9a66",
       "currency": "USD",
       "options": {
         "return_url": "http://www.google.com/?q=SUCCESS",
         "cancel_return_url": "http://www.google.com/?q=FAILURE",
         "billing_agreement": {
           "description": "Your subscription"
         }
       }
     }' \
     http://127.0.0.1:8080/plugins/killbill-paypal-express/1.0/setup-checkout

Kill Bill will return a 302 Found on success. The customer should be redirected to the url specified in the Location header, e.g. https://www.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token=EC-20G53990M6953444J.

Once the customer comes back from the PayPal flow, save the BAID in Kill Bill:

curl -v \
     -X POST \
     -u admin:password \
     -H 'X-Killbill-ApiKey: bob' \
     -H 'X-Killbill-ApiSecret: lazar' \
     -H 'X-Killbill-CreatedBy: admin' \
     -H 'Content-Type: application/json' \
     -d '{
       "pluginName": "killbill-paypal-express",
       "pluginInfo": {
         "properties": [{
           "key": "token",
           "value": "20G53990M6953444J"
         }]
       }
     }' \
     "http://127.0.0.1:8080/1.0/kb/accounts/13d26090-b8d7-11e2-9e96-0800200c9a66/paymentMethods?isDefault=true"

Plugin properties

Key Description
skip_gw If true, skip the call to PayPal
token PayPal token to use
payer_id PayPal Payer id to use
create_pending_payment Create pending payment during buildFormDescriptor call
payment_processor_account_id Config entry name of the merchant account to use
external_key_as_order_id If true, set the payment external key as the PayPal order id
email Purchaser email
address1 Billing address first line
address2 Billing address second line
city Billing address city
zip Billing address zip code
state Billing address state
country Billing address country

Below is a list of optional parameters for build_form_descriptor call. More details can be found on PayPal manual

Key Description
max_amount Maximum amount parameter
auth_mode If true, Authorization Payment Action is adopted. Otherwise, Sale Payment Action is used.
no_shipping Whether or not to show shipping address on PayPal checkout page
req_billing_address Is 1 or 0. The value 1 indicates that you require that the buyer’s billing address on file with PayPal be returned. Setting this element will return BILLTONAME, STREET, STREET2, CITY, STATE, ZIP, and COUNTRYCODE.
address_override Determines whether or not the PayPal pages should display the shipping address set by you in this SetExpressCheckout request, not the shipping address on file with PayPal for this buyer.
locale Locale of pages displayed by PayPal during Express Checkout. It is either a two-letter country code or five-character locale code supported by PayPal.
brand_name A label that overrides the business name in the PayPal account on the PayPal hosted checkout pages.
page_style Name of the Custom Payment Page Style for payment pages associated with this button or link. It corresponds to the HTML variable page_style for customizing payment pages.
logo_image A URL to your logo image. Use a valid graphics format, such as .gif, .jpg, or .png. Limit the image to 190 pixels wide by 60 pixels high.
header_image URL for the image you want to appear at the top left of the payment page. The image has a maximum size of 750 pixels wide by 90 pixels high.
header_border_color Sets the border color around the header of the payment page. The border is a 2-pixel perimeter around the header space, which is 750 pixels wide by 90 pixels high. By default, the color is black.
header_background_color Sets the background color for the header of the payment page. By default, the color is white.
background_color Sets the background color for the payment page. By default, the color is white.
allow_guest_checkout If set to true, then the SolutionType is Sole and buyer does not need to create a PayPal account to check out.
landing_page Type of PayPal page to display. It is one of the following values: Billing for Non-PayPal account and Login — PayPal account login.
email Email address of the buyer as entered during checkout. PayPal uses this value to pre-fill the PayPal membership sign-up portion on the PayPal pages.
allow_note Enables the buyer to enter a note to the merchant on the PayPal page during checkout.
callback_url URL to which the callback request from PayPal is sent. It must start with HTTPS for production integration.
callback_timeout An override for you to request more or less time to be able to process the callback request and respond.
allow_buyer_optin Enables the buyer to provide their email address on the PayPal pages to be notified of promotions or special events.
shipping_address Address to which the order is shipped. This parameter must be a JSON Hash with keys of name, address1, address2, state, city, country, phone, zip and phone.
address Address to which the order is shipped if shipping_address is not set. This parameter must be a JSON Hash with keys of name, address1, address2, state, city, country, phone, zip and phone.
total_type Type declaration for the label to be displayed in MiniCart for UX. It is one of the following values: Total or EstimatedTotal.
funding_sources This parameter must be in a JSON hash format with a key being source. This element could be used to specify the preferred funding option for a guest user. However, the landing_page element must also be set to Billing. Otherwise, it is ignored.
shipping_options This parameter must be in a JSON hash format with keys of default, amount, and name. This corresponds to the ShippingOptionsType in the SetupExpressCheckout call.
subtotal Sum of cost of all items in this order. For digital goods, this field is required.
shipping Total shipping costs for this order.
handling Total handling costs for this order.
tax Sum of tax for all items in this order.
insurance_total Total shipping insurance costs for this order. The value must be a non-negative currency amount or null if you offer insurance options.
shipping_discount Shipping discount for this order, specified as a negative number.
insurance_option_offered Indicates whether insurance is available as an option the buyer can choose on the PayPal Review page.
description Description of items the buyer is purchasing.
custom A free-form field for your own use.
order_id Your own invoice or tracking number.
invoice_id Your own invoice or tracking number. This will be overridden by order_id.
notify_url Your URL for receiving Instant Payment Notification (IPN) about this transaction. If you do not specify this value in the request, the notification URL from your Merchant Profile is used, if one exists.
items This parameter must be a JSON Array that contains a list of Hashes with keys of name, number, quantity, amount, description, url and category.
review If false, checkout button is set to Pay now.

Running the tests

In order to run the integration tests, you will need a valid: buyer credential; signature; api credentials. For new browsers you will also need to have Selenium standalone server running.

To run the Selenium standalone server:

  1. Download the Selenium standalone server version 3.13
  2. Start the server:
    • java -jar selenium-server-standalone-3.13.0.jar

Then run the tests with:

SIGNATURE="<the api signature>" \
LOGIN="<the api username>" \
PASSWORD="<the api password>" \
BUYER_USERNAME="<the buyer email id>" \
BUYER_PASSWORD="<the buyer password>" \
SELENIUM_STANDALONE_SERVER="true" \

killbill-paypal-express-plugin's People

Contributors

alenad avatar daliwei avatar killbillio avatar pierre avatar sbrossie avatar wwjbatista avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

killbill-paypal-express-plugin's Issues

getPaymentInfo regression

It looks like the result of the API call details_for is returned as part of the getPaymentInfo, causing failed payments to be returned as PROCESSED (i.e. success) by the plugin.

Incorrect 404 Not Found response when Accept header is invalid

The plugin returns 404 with body <h1>Not Found</h1> when a valid Accept header was not sent with the request. Since curl automatically adds an Accept: */* header it doesn't happen with curl, however, it is easy to reproduce by forcing curl to send an empty Accept header with the -H 'Accept:' argument.

If you modify the example from the readme then you can reproduce the issue:

curl -v \
     -X POST \
     -u admin:password \
     -H 'Accept:' \
     -H 'X-Killbill-ApiKey: bob' \
     -H 'X-Killbill-ApiSecret: lazar' \
     -H 'X-Killbill-CreatedBy: admin' \
     -H 'Content-Type: text/plain' \
     -d ':paypal_express:
  :signature: "your-paypal-signature"
  :login: "your-username-facilitator.something.com"
  :password: "your-password"' \
     http://127.0.0.1:8080/1.0/kb/tenants/uploadPluginConfig/killbill-paypal-express

I suggest returning 406: Not Acceptable instead.

Why does it need to be fixed: I'm using an advanced REST client that doesn't add Accept headers automatically, and I thought that something else was wrong because of the misleading response. Also, logs don't help either so I was left completely clueless. I wasted a day or so trying different versions of the plugin and Kill Bill to see if there is a version that works, and apparently no one has had the same issue before because I didn't find anything about this on the internet. If the response I got had been 406 it would have been trivial.

Recurring payments via a billing agreement ID (BAID) : Token expire

Hi,
i have followed the installation instructions and the Recurring payments via a billing agreement ID (BAID) instruction but on every recurring payment i get this message "This Express Checkout session has expired. Token value is no longer valid."
so there is any thing i'm missing or i have to do ?

Tests failures related to PayPal error codes

After merging #19, I'm getting quite a few errors such as:

  1) Killbill::PaypalExpress::PaymentPlugin hpp test with a single account should generate forms correctly
     Failure/Error: subsequent_purchase(properties)
       expected: nil
            got: "11607" (using ==)
     # ./spec/paypal_express/remote/hpp_spec_helpers.rb:352:in `failed_purchase'
     # ./spec/paypal_express/remote/hpp_spec_helpers.rb:312:in `subsequent_purchase'
     # ./spec/paypal_express/remote/hpp_spec.rb:49:in `(root)'
     # ./spec/paypal_express/remote/hpp_spec.rb:25:in `(root)'

They all seem to be related to assertions around gateway_error_code.

@alenad / @daliwei: are you seeing this as well? If so, can you look into it?

Add support for HPP flows

In order to support non-recurring payment flows (i.e. HPP flows), we need to:

Allow storage of empty payment methods

Implement build_form_descriptor

build_form_descriptor should call initiate_express_checkout to generate the token.
This call generates the redirect URL that can be saved in the form_url parameter.

Support one-off payments during the complete flow

See here: the token and payerId need to be retrieved from the properties instead of the payment method. We also need to fix our implementation to support both BAID and one-off flows (see here for instance): luckily both are already supported by ActiveMerchant.

Support creating pending payments

By default, pending payments are not created for HPP. We should add an option to do it, similar to Adyen or the PayU plugin:

That way, during the complete call (i.e. purchase with an existing payment id specified), Kill Bill can transition the payment from PENDING to SUCCESS.

Production mode doesn't work

Hi all,

As mention in the readme file for go to production need to create file paypal_express.yml configuration file under /var/tmp/bundles/plugins/ruby/killbill-paypal-express/x.y.z/ containing the following:

:paypal_express:
  :test: false

I am using KillBill 0.20.11 with paypal-express plugin version of 6.0.0
If I properly understood the instruction above I have to create /var/tmp/bundles/plugins/ruby/killbill-paypal-express/6.0.0/paypal_express.yml containing mentioned above content.

Am I doing something wrong? Because the instruction doesn't work as expected, the plugin still trying to connect to paypal's sandbox api.

Thank you.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.