This is the new donation system for the Survival International site.
This gem is still under development and in an unstable state. Hence, it is not in rubygems yet.
To install it, add this line to your application's Gemfile:
gem 'donation-system', git: 'https://github.com/survival/donation-system'
and run bundle install
. Then append bundle exec
in front of any CLI command that requires this gem.
require 'donation_system'
Data = Struct.new(
:type, :amount, :currency, :giftaid, :token,
:name, :email,
:address, :city, :state, :zip, :country,
:method
)
data = Data.new(
'one-off', '10.50', 'gbp', true, 'tok_visa',
'Jane Doe', '[email protected]',
'Main Street, 1', 'London', 'London', 'Z1PC0D3', 'UK',
'stripe'
)
errors = DonationSystem::Payment.attempt(data)
if errors.empty?
# Do something cool
else
# Log errors, maybe
end
For PayPal tokens, you need two things: a payment id, and a payer id, hence:
PaypalToken = Struct.new(:payment_id, :payer_id)
token = PaypalToken.new('PAY-13J25512E99606838LJU7M4Y', 'DUFRQ8GWYMJXC')
If there are no errors, it means that:
- The payment was saved in your Stripe/PayPal account
- A thank you email was sent to the donor
- The relevant records were saved in Salesforce (a one-off donation and a new supporter if they didn't exist in the database)
The data
that the gem consumes can be anything that responds to at least the following (all these should return strings except the giftaid, which is a boolean):
data.type
: The type of donation. Valid values:'one-off'
for one-off donations or'recurring'
for recurring dontaions.data.amount
: The amount of money to be donated, in currency units. This can be an amount with cents, and will be converted to cents by the gem. For example: 10.50data.currency
: The currency that the amount is in, should be a valid ISO 4217 code for currencies and supported by the Money gem, which is used by this gem to handle money. Check here for a list of supported currencies in JSON formatdata.giftaid
: This can be true or false, depending if you allow the donors to Gift Aid their donation to youdata.token
is a one-use valid token generated by Stripe, or the payment and payer ids generated by PayPal. To get them you need to use their JavaScript libraries in the frontenddata.name
: the name of the donordata.email
: the email of the donordata.address
: the address of the donordata.city
: the city of the donordata.state
: the state of the donordata.zip
: the zip code of the donordata.country
: the country of the donordata.method
: the payment method. Valid values:'stripe'
for Stripe donations or'paypal'
for PayPal donations.
Due to an error thrown by the Money
gem (see this issue) you will also have to set this in some relevant place of your application:
I18n.enforce_available_locales = false
For the gem to work you need to set some environment variables:
-
The Stripe API keys of your Stripe account:
export STRIPE_SECRET_KEY=... export STRIPE_PUBLIC_KEY=...
-
The PayPal API keys of your PayPal account:
export PAYPAL_MODE=... # 'sandbox' or 'live' only export PAYPAL_CLIENT_ID=... export PAYPAL_CLIENT_SECRET=...
-
Your email server data:
export EMAIL_SERVER=... export EMAIL_USERNAME=... export EMAIL_PASSWORD=...
-
Some data from your Salesforce account:
export SALESFORCE_HOST=... export SALESFORCE_USERNAME=... export SALESFORCE_PASSWORD=... export SALESFORCE_SECURITY_TOKEN=... export SALESFORCE_CLIENT_ID=... export SALESFORCE_CLIENT_SECRET=... export SALESFORCE_API_VERSION=...
NOTE: If the Salesforce password is updated, the security token will have to be updated at the same time. The new token should be provided in the email confirming a change of password.
These variables are set in Travis and Heroku as well so that the tests are green and the applicaiton runs. Everytime you need to add new credentials or update existing ones, remember to also update:
- The credentials repo (test credentials only)
- Travis (test credentials only)
- Heroku staging (production credentials only)
- Heroku production (poduction credentials only)
Use their JavaScript library in the frontend (i.e., Stripe Checkout custom integration) to send the supporter card data and receive a token for that card. Then send the form data and the token to your server and use this gem as in the example above to make the payment.
This gem uses the new PayPal express checkout
As opposed to Stripe, the PayPal REST SDK
needs an extra previous step
where your server creates a payment and returns the id to the checkout.js
library. PayPal doesn't allow you to have a custom button anymore, so you have to use their PayPal button, which will be injected in an iframe
.
require 'donation_system'
Data = Struct.new(:amount, :currency, :return_url, :cancel_url)
data = PaypalCreatorData.new(
'12.345', 'gbp', 'https://your-return-url.com', 'https://your-cancel-url.com'
).freeze
result = DonationSystem::PaypalWrapper::PaymentCreator.execute(data)
if result.okay?
# Pass the payment id (result.item.id ) to the checkout.js library
else
# Log result.errors, maybe
end
The return url is an endpoint in your web application where PayPal should send the supporter once they have authorized the payment. The cancel url is another endpoint in your application where PayPal will send the user if they cancel the payment.
Once you have passed the payment id to the checkout.js library, a pop-up will open for the donor to authorize the payment. After authorization, Paypal will call the onAuthorize
method in the client, where you can then use this gem as in the example above to make the payment.
You need to have git
and bundler
installed.
Run the setup script (Beware: Needs permissions to access the credentials repo):
. ./scripts/setup.sh
This script will:
- download the credentials
- run the credentials to set the environment
- run
bundle install
to install gems. - run
bundle exec rake
to run the tests.
You need to set your environment by running the credentials. These will be loaded when you run the setup.sh
script, but will also be loaded when you run the tests as described below. Make sure your credentials are up to date:
cd credentials && git push origin master && cd -
Currently, when you run the tests, any HTTP request will be recorded once in spec/cassettes
, which are then replayed every time you run the tests. So the first time that you run them, they will take a while, but once they are recorded, they should run fast. Also, the first time you run the tests, you need to be connected to the internet.
If you ever get any weird errors when running the tests, try removing the cassettes and then running the tests again:
rm -rf spec/cassettes
bundle exec rake
This folder is safe to delete as it will be regenerated by the tests if it doesn't exist.
. ./test.sh
bundle exec rspec path/to/test/file.rb && rubocop
bundle exec rspec path/to/test/file.rb:TESTLINENUMBER && rubocop
Note: You may see a failing test for setting up Stripe subscriptions if the number of subscriptions for the test user exceeds 25. To solve this error, it is necessary to log on to the Stripe dashboard and delete previous subscriptions for the test user.
To release a new version, update the version number in version.rb
, and describe your changes in the changelog. Then run:
git tag -a VERSION_HERE -m "DESCRIPTION_HERE"
which will create a git tag for the version. Then push git commits and tags:
git push origin master --tags
and push the .gem
file to rubygems.org:
gem build donation_system.gemspec
gem push donation_system-VERSION_HERE.gem
You can send an email to any email address using the test_email_server.rb
script, and making sure that you set your environment with an email server, username and password, by running the credentials:
. credentials/.email_server
bundle exec ruby scripts/test_email_server.rb 'YOUR_EMAIL_HERE'
Please check out our contribution guides and our code of conduct