├── .github ├── CODEOWNERS ├── ISSUE_TEMPLATE.md └── PULL_REQUEST_TEMPLATE.md ├── .gitignore ├── .rubocop.yml ├── ACKNOWLEDGEMENTS.md ├── CHANGELOG.md ├── Dockerfile ├── Gemfile ├── Jenkinsfile ├── LICENSE ├── Makefile ├── README.md ├── Rakefile ├── braintree.gemspec ├── ci.sh ├── env └── development.rb ├── lib ├── braintree.rb ├── braintree │ ├── account_updater_daily_report.rb │ ├── ach_mandate.rb │ ├── add_on.rb │ ├── add_on_gateway.rb │ ├── address.rb │ ├── address │ │ └── country_names.rb │ ├── address_gateway.rb │ ├── advanced_search.rb │ ├── apple_pay.rb │ ├── apple_pay_card.rb │ ├── apple_pay_gateway.rb │ ├── apple_pay_options.rb │ ├── authorization_adjustment.rb │ ├── base_module.rb │ ├── bin_data.rb │ ├── client_token.rb │ ├── client_token_gateway.rb │ ├── configuration.rb │ ├── connected_merchant_paypal_status_changed.rb │ ├── connected_merchant_status_transitioned.rb │ ├── credentials_parser.rb │ ├── credit_card.rb │ ├── credit_card_gateway.rb │ ├── credit_card_verification.rb │ ├── credit_card_verification_gateway.rb │ ├── credit_card_verification_search.rb │ ├── customer.rb │ ├── customer_gateway.rb │ ├── customer_search.rb │ ├── customer_session_gateway.rb │ ├── descriptor.rb │ ├── digest.rb │ ├── disbursement.rb │ ├── discount.rb │ ├── discount_gateway.rb │ ├── dispute.rb │ ├── dispute │ │ ├── evidence.rb │ │ ├── paypal_message.rb │ │ ├── status_history.rb │ │ ├── transaction.rb │ │ └── transaction_details.rb │ ├── dispute_gateway.rb │ ├── dispute_search.rb │ ├── document_upload.rb │ ├── document_upload_gateway.rb │ ├── enriched_customer_data.rb │ ├── error_codes.rb │ ├── error_result.rb │ ├── errors.rb │ ├── exceptions.rb │ ├── exchange_rate.rb │ ├── exchange_rate_quote.rb │ ├── exchange_rate_quote_gateway.rb │ ├── exchange_rate_quote_input.rb │ ├── exchange_rate_quote_request.rb │ ├── exchange_rate_quote_response.rb │ ├── facilitated_details.rb │ ├── facilitator_details.rb │ ├── gateway.rb │ ├── google_pay_card.rb │ ├── granted_payment_instrument_update.rb │ ├── graphql │ │ ├── enums │ │ │ ├── recommendations.rb │ │ │ └── recommended_payment_option.rb │ │ ├── inputs │ │ │ ├── create_customer_session_input.rb │ │ │ ├── customer_recommendations_input.rb │ │ │ ├── customer_session_input.rb │ │ │ ├── monetary_amount_input.rb │ │ │ ├── paypal_payee_input.rb │ │ │ ├── paypal_purchase_unit_input.rb │ │ │ ├── phone_input.rb │ │ │ └── update_customer_session_input.rb │ │ ├── types │ │ │ ├── customer_recommendations_payload.rb │ │ │ ├── payment_options.rb │ │ │ └── payment_recommendations.rb │ │ └── unions │ │ │ └── customer_recommendations.rb │ ├── graphql_client.rb │ ├── http.rb │ ├── local_payment_completed.rb │ ├── local_payment_completed │ │ └── blik_alias.rb │ ├── local_payment_expired.rb │ ├── local_payment_funded.rb │ ├── local_payment_reversed.rb │ ├── merchant.rb │ ├── merchant_account.rb │ ├── merchant_account │ │ └── address_details.rb │ ├── merchant_account_gateway.rb │ ├── merchant_gateway.rb │ ├── meta_checkout_card.rb │ ├── meta_checkout_token.rb │ ├── modification.rb │ ├── oauth_credentials.rb │ ├── oauth_gateway.rb │ ├── paginated_collection.rb │ ├── paginated_result.rb │ ├── payment_instrument_type.rb │ ├── payment_method.rb │ ├── payment_method_customer_data_updated_metadata.rb │ ├── payment_method_gateway.rb │ ├── payment_method_nonce.rb │ ├── payment_method_nonce_details.rb │ ├── payment_method_nonce_details_payer_info.rb │ ├── payment_method_nonce_gateway.rb │ ├── payment_method_parser.rb │ ├── paypal_account.rb │ ├── paypal_account_gateway.rb │ ├── paypal_payment_resource.rb │ ├── paypal_payment_resource_gateway.rb │ ├── plan.rb │ ├── plan_gateway.rb │ ├── processor_response_types.rb │ ├── resource_collection.rb │ ├── revoked_payment_method_metadata.rb │ ├── risk_data.rb │ ├── risk_data │ │ └── liability_shift.rb │ ├── samsung_pay_card.rb │ ├── sepa_direct_debit_account.rb │ ├── sepa_direct_debit_account_gateway.rb │ ├── sepa_direct_debit_account_nonce_details.rb │ ├── settlement_batch_summary.rb │ ├── settlement_batch_summary_gateway.rb │ ├── sha256_digest.rb │ ├── signature_service.rb │ ├── subscription.rb │ ├── subscription │ │ └── status_details.rb │ ├── subscription_gateway.rb │ ├── subscription_search.rb │ ├── successful_result.rb │ ├── test │ │ ├── authentication_id.rb │ │ ├── credit_card.rb │ │ ├── merchant_account.rb │ │ ├── nonce.rb │ │ ├── transaction_amounts.rb │ │ └── venmo_sdk.rb │ ├── test_transaction.rb │ ├── testing_gateway.rb │ ├── three_d_secure_info.rb │ ├── transaction.rb │ ├── transaction │ │ ├── address_details.rb │ │ ├── apple_pay_details.rb │ │ ├── credit_card_details.rb │ │ ├── customer_details.rb │ │ ├── disbursement_details.rb │ │ ├── google_pay_details.rb │ │ ├── installment.rb │ │ ├── installment │ │ │ └── adjustment.rb │ │ ├── local_payment_details.rb │ │ ├── meta_checkout_card_details.rb │ │ ├── meta_checkout_token_details.rb │ │ ├── package_details.rb │ │ ├── payment_receipt.rb │ │ ├── payment_receipt │ │ │ ├── card_present_data.rb │ │ │ └── merchant_address.rb │ │ ├── paypal_details.rb │ │ ├── paypal_here_details.rb │ │ ├── samsung_pay_card_details.rb │ │ ├── sepa_direct_debit_account_details.rb │ │ ├── status_details.rb │ │ ├── subscription_details.rb │ │ ├── us_bank_account_details.rb │ │ ├── venmo_account_details.rb │ │ └── visa_checkout_card_details.rb │ ├── transaction_gateway.rb │ ├── transaction_line_item.rb │ ├── transaction_line_item_gateway.rb │ ├── transaction_review.rb │ ├── transaction_search.rb │ ├── unknown_payment_method.rb │ ├── us_bank_account.rb │ ├── us_bank_account_gateway.rb │ ├── us_bank_account_verification.rb │ ├── us_bank_account_verification_gateway.rb │ ├── us_bank_account_verification_search.rb │ ├── util.rb │ ├── validation_error.rb │ ├── validation_error_collection.rb │ ├── venmo_account.rb │ ├── venmo_profile_data.rb │ ├── version.rb │ ├── visa_checkout_card.rb │ ├── webhook_notification.rb │ ├── webhook_notification_gateway.rb │ ├── webhook_testing.rb │ ├── webhook_testing_gateway.rb │ ├── xml.rb │ └── xml │ │ ├── generator.rb │ │ ├── libxml.rb │ │ ├── parser.rb │ │ └── rexml.rb └── ssl │ ├── api_braintreegateway_com.ca.crt │ └── securetrust_ca.crt ├── polaris.yml └── spec ├── .gitignore ├── fixtures └── files │ ├── bt_logo.png │ ├── gif_extension_bt_logo.gif │ ├── malformed_pdf.pdf │ └── too_long.pdf ├── integration ├── braintree │ ├── add_on_spec.rb │ ├── address_spec.rb │ ├── advanced_search_spec.rb │ ├── apple_pay_spec.rb │ ├── braintree_gateway_spec.rb │ ├── client_api │ │ ├── client_token_spec.rb │ │ └── spec_helper.rb │ ├── credit_card_spec.rb │ ├── credit_card_verification_search_spec.rb │ ├── credit_card_verification_spec.rb │ ├── customer_search_spec.rb │ ├── customer_session_spec.rb │ ├── customer_spec.rb │ ├── disbursement_spec.rb │ ├── discount_spec.rb │ ├── dispute_search_spec.rb │ ├── dispute_spec.rb │ ├── document_upload_spec.rb │ ├── error_codes_spec.rb │ ├── exchange_rate_quote_spec.rb │ ├── graphql_client_spec.rb │ ├── http_spec.rb │ ├── merchant_account_spec.rb │ ├── merchant_spec.rb │ ├── oauth_spec.rb │ ├── package_tracking_spec.rb │ ├── payment_method_nonce_spec.rb │ ├── payment_method_spec.rb │ ├── payment_method_us_bank_account_spec.rb │ ├── paypal_account_spec.rb │ ├── paypal_payment_resource_spec.rb │ ├── plan_spec.rb │ ├── samsung_pay_card_spec.rb │ ├── sepa_direct_debit_account_spec.rb │ ├── settlement_batch_summary_spec.rb │ ├── subscription_spec.rb │ ├── test │ │ └── transaction_amounts_spec.rb │ ├── test_transaction_spec.rb │ ├── transaction_line_item_spec.rb │ ├── transaction_payment_facilitator_spec.rb │ ├── transaction_search_spec.rb │ ├── transaction_spec.rb │ ├── transaction_us_bank_account_spec.rb │ ├── us_bank_account_spec.rb │ ├── us_bank_account_verification_search_spec.rb │ ├── us_bank_account_verification_spec.rb │ └── visa_checkout_card_spec.rb └── spec_helper.rb ├── oauth_test_helper.rb ├── script └── httpsd.rb ├── spec.opts ├── spec_helper.rb ├── ssl ├── certificate.crt ├── geotrust_global.crt └── privateKey.key └── unit ├── braintree ├── address_spec.rb ├── apple_pay_card_spec.rb ├── base_module_spec.rb ├── client_token_spec.rb ├── configuration_spec.rb ├── credentials_parser_spec.rb ├── credit_card_spec.rb ├── credit_card_verification_gateway_spec.rb ├── credit_card_verification_search_spec.rb ├── credit_card_verification_spec.rb ├── customer_session_gateway_spec.rb ├── customer_spec.rb ├── digest_spec.rb ├── dispute_search_spec.rb ├── dispute_spec.rb ├── document_upload_spec.rb ├── enriched_customer_data_spec.rb ├── error_result_spec.rb ├── errors_spec.rb ├── exchange_rate_quote_input_spec.rb ├── exchange_rate_quote_request_spec.rb ├── exchange_rate_quote_response_spec.rb ├── exchange_rate_quote_spec.rb ├── exchange_rate_spec.rb ├── google_pay_card_spec.rb ├── graphql │ ├── create_customer_session_input_spec.rb │ ├── customer_recommendations_input_spec.rb │ ├── customer_recommendations_spec.rb │ ├── customer_session_input_spec.rb │ ├── phone_input_spec.rb │ └── update_customer_session_input_spec.rb ├── graphql_client_spec.rb ├── http_spec.rb ├── local_payment_completed_spec.rb ├── local_payment_expired_spec.rb ├── local_payment_funded_spec.rb ├── meta_checkout_card_details_spec.rb ├── meta_checkout_card_spec.rb ├── meta_checkout_token_details_spec.rb ├── meta_checkout_token_spec.rb ├── modification_spec.rb ├── package_tracking_spec.rb ├── payment_method_customer_data_updated_metadata_spec.rb ├── payment_method_nonce_details_payer_info_spec.rb ├── payment_method_nonce_details_spec.rb ├── payment_method_nonce_spec.rb ├── payment_method_spec.rb ├── paypal_account_spec.rb ├── paypal_payment_resource_spec.rb ├── resource_collection_spec.rb ├── risk_data │ └── liability_shift.rb ├── risk_data_spec.rb ├── sepa_debit_account_nonce_details_spec.rb ├── sepa_debit_account_spec.rb ├── sha256_digest_spec.rb ├── signature_service_spec.rb ├── subscription_search_spec.rb ├── subscription_spec.rb ├── successful_result_spec.rb ├── three_d_secure_info_spec.rb ├── transaction │ ├── apple_pay_details_spec.rb │ ├── credit_card_details_spec.rb │ ├── customer_details_spec.rb │ ├── deposit_details_spec.rb │ ├── google_pay_details_spec.rb │ ├── installment_spec.rb │ ├── local_payment_details_spec.rb │ ├── meta_checkout_card_details_spec.rb │ ├── meta_checkout_token_details_spec.rb │ ├── payment_receipt_spec.rb │ ├── paypal_details_spec.rb │ ├── sepa_direct_debit_account_details_spec.rb │ └── visa_checkout_card_details_spec.rb ├── transaction_gateway_spec.rb ├── transaction_search_spec.rb ├── transaction_spec.rb ├── unknown_payment_method_spec.rb ├── us_bank_account_spec.rb ├── us_bank_account_verification_search_spec.rb ├── us_bank_account_verification_spec.rb ├── util_spec.rb ├── validation_error_collection_spec.rb ├── validation_error_spec.rb ├── venmo_profile_data_spec.rb ├── visa_checkout_card_spec.rb ├── webhook_notification_spec.rb ├── xml │ ├── libxml_spec.rb │ ├── parser_spec.rb │ └── rexml_spec.rb └── xml_spec.rb ├── braintree_spec.rb ├── credit_card_details_spec.rb └── spec_helper.rb /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | * @PayPal-Braintree/team-sdk-server 2 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ### General information 4 | 5 | * SDK/Library version: 6 | * Environment: 7 | * Language, language version, and OS: 8 | 9 | ### Issue description 10 | 11 | 12 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | # Summary 2 | 3 | (Please provide any information that can give us context on _why_ you're submitting this PR). 4 | 5 | # Checklist 6 | - [ ] Added changelog entry (If there isn't an `#unreleased` section, add that and your changelog entry to the top of the changelog) 7 | - [ ] Ran unit tests (`rake test:unit`) 8 | - [ ] I alphabetized all attributes, parameters, and methods by name in any class file I changed 9 | - [ ] I have linked the JIRA ticket in the summary section 10 | - [ ] I have reviewed the JIRA ticket to ensure all AC's are met 11 | - [ ] I understand that unless this is a Draft PR or has a DO NOT MERGE label, this PR is considered to be in a deploy ready state and can be deployed if merged to main 12 | 13 | 16 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | bt_rdoc 2 | rdoc 3 | *.gem 4 | tags 5 | .rvmrc 6 | Gemfile.lock 7 | .idea 8 | .bundle 9 | vendor 10 | -------------------------------------------------------------------------------- /ACKNOWLEDGEMENTS.md: -------------------------------------------------------------------------------- 1 | Acknowledgements 2 | ---------------- 3 | 4 | The Braintree SDK uses code from the following libraries: 5 | 6 | * [builder](https://github.com/jimweirich/builder), MIT License 7 | * [libxml-ruby](https://github.com/xml4r/libxml-ruby), MIT License 8 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM debian:buster 2 | 3 | RUN apt-get update 4 | RUN apt-get -y install gnupg curl procps build-essential libxml2-dev 5 | RUN gpg -vvvv --keyserver keys.openpgp.org --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB 6 | RUN curl -sSL https://get.rvm.io | bash 7 | RUN bash -l -c "rvm requirements" 8 | RUN bash -l -c "rvm install 3.0.1" 9 | RUN bash -l -c "gem install bundler" 10 | 11 | WORKDIR /braintree-ruby 12 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source "https://rubygems.org" 2 | 3 | gem "builder", "3.2.4" 4 | gem "libxml-ruby", "3.2.0" 5 | gem "require_all", "3.0.0" 6 | 7 | group :development do 8 | gem "pry", "0.13.1" 9 | gem "rake", "13.0.1" 10 | gem "rspec", "3.9.0" 11 | gem "rubocop", "1.50.2" 12 | gem "webrick", "~>1.7.0" 13 | end 14 | 15 | group :test do 16 | gem "rspec_junit_formatter" 17 | end 18 | -------------------------------------------------------------------------------- /Jenkinsfile: -------------------------------------------------------------------------------- 1 | #!groovy 2 | 3 | def FAILED_STAGE 4 | 5 | pipeline { 6 | agent { 7 | node { 8 | label "ec2" 9 | customWorkspace "workspace/braintree-ruby" 10 | } 11 | } 12 | environment { 13 | SLACK_CHANNEL = "#auto-team-sdk-builds" 14 | } 15 | 16 | options { 17 | buildDiscarder(logRotator(numToKeepStr: '50')) 18 | timestamps() 19 | timeout(time: 120, unit: 'MINUTES') 20 | } 21 | 22 | stages { 23 | stage("CodeQL") { 24 | steps { 25 | script { 26 | codeQLv2(ruby: true) 27 | } 28 | } 29 | 30 | post { 31 | failure { 32 | script { 33 | FAILED_STAGE = env.STAGE_NAME 34 | } 35 | } 36 | } 37 | } 38 | } 39 | 40 | post { 41 | unsuccessful { 42 | slackSend color: "danger", 43 | channel: "${env.SLACK_CHANNEL}", 44 | message: "${env.JOB_NAME} - #${env.BUILD_NUMBER} Failure after ${currentBuild.durationString} at stage \"${FAILED_STAGE}\"(<${env.BUILD_URL}|Open>)" 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2009-2020 Braintree, a division of PayPal, Inc. 2 | 3 | Permission is hereby granted, free of charge, to any person 4 | obtaining a copy of this software and associated documentation 5 | files (the "Software"), to deal in the Software without 6 | restriction, including without limitation the rights to use, 7 | copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the 9 | Software is furnished to do so, subject to the following 10 | conditions: 11 | 12 | The above copyright notice and this permission notice shall be 13 | included in all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 17 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 19 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 20 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: console build 2 | 3 | console: build 4 | docker run -it -v="$(PWD):/braintree-ruby" --net="host" braintree-ruby /bin/bash -l -c "bundle install;bash -l" 5 | 6 | build: 7 | docker build -t braintree-ruby . 8 | 9 | lint: build 10 | docker run -i -v="$(PWD):/braintree-ruby" --net="host" braintree-ruby /bin/bash -l -c "bundle install;rake lint" 11 | -------------------------------------------------------------------------------- /braintree.gemspec: -------------------------------------------------------------------------------- 1 | $:.push File.expand_path("../lib", __FILE__) 2 | require "braintree/version" 3 | 4 | Gem::Specification.new do |s| 5 | s.name = "braintree" 6 | s.summary = "Braintree Ruby Server SDK" 7 | s.description = "Resources and tools for developers to integrate Braintree's global payments platform." 8 | s.version = Braintree::Version::String 9 | s.license = "MIT" 10 | s.author = "Braintree" 11 | s.email = "code@getbraintree.com" 12 | s.homepage = "https://www.braintreepayments.com/" 13 | s.files = Dir.glob ["README.rdoc", "LICENSE", "lib/**/*.{rb,crt}", "spec/**/*", "*.gemspec"] 14 | s.add_dependency "builder", ">= 3.2.4" 15 | s.add_dependency "rexml", ">= 3.1.9" # Use rexml version associated with minimum supported Ruby version 16 | s.required_ruby_version = ">=2.6.0" 17 | s.metadata = { 18 | "bug_tracker_uri" => "https://github.com/braintree/braintree_ruby/issues", 19 | "changelog_uri" => "https://github.com/braintree/braintree_ruby/blob/master/CHANGELOG.md", 20 | "source_code_uri" => "https://github.com/braintree/braintree_ruby", 21 | "documentation_uri" => "https://developer.paypal.com/braintree/docs" 22 | } 23 | end 24 | 25 | -------------------------------------------------------------------------------- /ci.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | source "$HOME/.rvm/scripts/rvm" 4 | 5 | if [ $# -eq 0 ]; then 6 | bundle exec rake --trace 7 | else 8 | rvm use $1 --create --install 9 | gem install bundler 10 | bundle install 11 | bundle exec rake --trace 12 | fi 13 | -------------------------------------------------------------------------------- /env/development.rb: -------------------------------------------------------------------------------- 1 | Braintree::Configuration.environment = :development 2 | Braintree::Configuration.merchant_id = "integration_merchant_id" 3 | Braintree::Configuration.public_key = "integration_public_key" 4 | Braintree::Configuration.private_key = "integration_private_key" 5 | # Braintree::Configuration.logger = Logger.new("/dev/null") 6 | -------------------------------------------------------------------------------- /lib/braintree/account_updater_daily_report.rb: -------------------------------------------------------------------------------- 1 | module Braintree 2 | class AccountUpdaterDailyReport 3 | include BaseModule 4 | 5 | attr_reader :report_date 6 | attr_reader :report_url 7 | 8 | class << self 9 | protected :new 10 | def _new(*args) 11 | self.new(*args) 12 | end 13 | end 14 | 15 | def initialize(attributes) 16 | set_instance_variables_from_hash(attributes) 17 | @report_date = Date.parse(report_date) 18 | end 19 | end 20 | end 21 | -------------------------------------------------------------------------------- /lib/braintree/ach_mandate.rb: -------------------------------------------------------------------------------- 1 | module Braintree 2 | class AchMandate 3 | include BaseModule 4 | 5 | attr_reader :accepted_at 6 | attr_reader :text 7 | 8 | def initialize(attributes) 9 | set_instance_variables_from_hash(attributes) 10 | @accepted_at = Time.parse(attributes[:accepted_at]) unless @accepted_at.class == Time 11 | end 12 | 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /lib/braintree/add_on.rb: -------------------------------------------------------------------------------- 1 | module Braintree 2 | class AddOn < Modification 3 | 4 | def self.all 5 | Configuration.gateway.add_on.all 6 | end 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /lib/braintree/add_on_gateway.rb: -------------------------------------------------------------------------------- 1 | module Braintree 2 | class AddOnGateway 3 | def initialize(gateway) 4 | @gateway = gateway 5 | @config = gateway.config 6 | @config.assert_has_access_token_or_keys 7 | end 8 | 9 | def all 10 | response = @config.http.get("#{@config.base_merchant_path}/add_ons") 11 | attributes_collection = response[:add_ons] 12 | attributes_collection.map do |attributes| 13 | AddOn._new(attributes) 14 | end 15 | end 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /lib/braintree/address.rb: -------------------------------------------------------------------------------- 1 | module Braintree 2 | class Address 3 | include BaseModule 4 | 5 | attr_reader :company 6 | attr_reader :country_code_alpha2 7 | attr_reader :country_code_alpha3 8 | attr_reader :country_code_numeric 9 | attr_reader :country_name 10 | attr_reader :created_at 11 | attr_reader :customer_id 12 | attr_reader :extended_address 13 | attr_reader :first_name 14 | attr_reader :id 15 | attr_reader :international_phone 16 | attr_reader :last_name 17 | attr_reader :locality 18 | attr_reader :phone_number 19 | attr_reader :postal_code 20 | attr_reader :region 21 | attr_reader :street_address 22 | attr_reader :updated_at 23 | 24 | def self.create(*args) 25 | Configuration.gateway.address.create(*args) 26 | end 27 | 28 | def self.create!(*args) 29 | Configuration.gateway.address.create!(*args) 30 | end 31 | 32 | def self.delete(*args) 33 | Configuration.gateway.address.delete(*args) 34 | end 35 | 36 | def self.find(*args) 37 | Configuration.gateway.address.find(*args) 38 | end 39 | 40 | def self.update(*args) 41 | Configuration.gateway.address.update(*args) 42 | end 43 | 44 | def self.update!(*args) 45 | Configuration.gateway.address.update!(*args) 46 | end 47 | 48 | def initialize(gateway, attributes) 49 | @gateway = gateway 50 | set_instance_variables_from_hash(attributes) 51 | end 52 | 53 | def ==(other) 54 | return false unless other.is_a?(Address) 55 | id == other.id && customer_id == other.customer_id 56 | end 57 | 58 | class << self 59 | protected :new 60 | end 61 | 62 | def self._new(*args) 63 | self.new(*args) 64 | end 65 | end 66 | end 67 | -------------------------------------------------------------------------------- /lib/braintree/apple_pay.rb: -------------------------------------------------------------------------------- 1 | module Braintree 2 | class ApplePay 3 | include BaseModule 4 | 5 | def initialize(gateway, attributes) 6 | set_instance_variables_from_hash(attributes) 7 | end 8 | 9 | class << self 10 | protected :new 11 | end 12 | 13 | def self._new(*args) 14 | self.new(*args) 15 | end 16 | 17 | def self.register_domain(domain) 18 | Configuration.gateway.apple_pay.register_domain(domain) 19 | end 20 | 21 | def self.unregister_domain(domain) 22 | Configuration.gateway.apple_pay.unregister_domain(domain) 23 | end 24 | 25 | def self.registered_domains 26 | Configuration.gateway.apple_pay.registered_domains 27 | end 28 | end 29 | end 30 | -------------------------------------------------------------------------------- /lib/braintree/apple_pay_gateway.rb: -------------------------------------------------------------------------------- 1 | module Braintree 2 | class ApplePayGateway 3 | def initialize(gateway) 4 | @gateway = gateway 5 | @config = gateway.config 6 | end 7 | 8 | def register_domain(domain) 9 | response = @config.http.post("#{@config.base_merchant_path}/processing/apple_pay/validate_domains", :url => domain) 10 | 11 | if response.has_key?(:response) && response[:response][:success] 12 | Braintree::SuccessfulResult.new 13 | elsif response[:api_error_response] 14 | ErrorResult.new(@gateway, response[:api_error_response]) 15 | else 16 | raise "expected :response or :api_error_response" 17 | end 18 | end 19 | 20 | def unregister_domain(domain) 21 | @config.http.delete("#{@config.base_merchant_path}/processing/apple_pay/unregister_domain", :url => CGI.escape(domain)) 22 | SuccessfulResult.new 23 | end 24 | 25 | def registered_domains 26 | response = @config.http.get("#{@config.base_merchant_path}/processing/apple_pay/registered_domains") 27 | 28 | if response.has_key?(:response) 29 | Braintree::SuccessfulResult.new(:apple_pay_options => ApplePayOptions._new(response[:response])) 30 | elsif response[:api_error_response] 31 | ErrorResult.new(@gateway, response[:api_error_response]) 32 | else 33 | raise "expected :response or :api_error_response" 34 | end 35 | end 36 | end 37 | end 38 | -------------------------------------------------------------------------------- /lib/braintree/apple_pay_options.rb: -------------------------------------------------------------------------------- 1 | module Braintree 2 | class ApplePayOptions 3 | include BaseModule 4 | 5 | attr_reader :domains 6 | 7 | def initialize(attributes) 8 | set_instance_variables_from_hash(attributes) 9 | end 10 | 11 | class << self 12 | protected :new 13 | end 14 | 15 | def self._new(*args) 16 | self.new(*args) 17 | end 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /lib/braintree/authorization_adjustment.rb: -------------------------------------------------------------------------------- 1 | module Braintree 2 | class AuthorizationAdjustment 3 | include BaseModule 4 | 5 | attr_reader :amount 6 | attr_reader :success 7 | attr_reader :timestamp 8 | attr_reader :processor_response_code 9 | attr_reader :processor_response_text 10 | attr_reader :processor_response_type 11 | 12 | class << self 13 | protected :new 14 | def _new(*args) 15 | self.new(*args) 16 | end 17 | end 18 | 19 | def initialize(attributes) 20 | set_instance_variables_from_hash(attributes) 21 | end 22 | end 23 | end 24 | -------------------------------------------------------------------------------- /lib/braintree/base_module.rb: -------------------------------------------------------------------------------- 1 | module Braintree 2 | module BaseModule 3 | module Methods 4 | def return_object_or_raise(object_to_return) 5 | result = yield 6 | if result.success? 7 | result.send object_to_return 8 | else 9 | raise ValidationsFailed.new(result) 10 | end 11 | end 12 | 13 | def copy_instance_variables_from_object(object) 14 | object.instance_variables.each do |ivar| 15 | instance_variable_set ivar, object.instance_variable_get(ivar) 16 | end 17 | end 18 | 19 | def set_instance_variables_from_hash(hash) 20 | hash.each do |key, value| 21 | if key == :global_id 22 | instance_variable_set "@graphql_id", value 23 | elsif key == :android_pay_cards 24 | instance_variable_set "@google_pay_cards", value 25 | elsif key == :android_pay_card 26 | instance_variable_set "@google_pay_card", value 27 | elsif key == :android_pay_details 28 | instance_variable_set "@google_pay_details", value 29 | end 30 | 31 | instance_variable_set "@#{key}", value 32 | end 33 | end 34 | 35 | def singleton_class 36 | class << self; self; end 37 | end 38 | end 39 | 40 | def self.included(klass) 41 | klass.extend Methods 42 | end 43 | include Methods 44 | end 45 | end 46 | -------------------------------------------------------------------------------- /lib/braintree/bin_data.rb: -------------------------------------------------------------------------------- 1 | module Braintree 2 | class BinData 3 | include BaseModule 4 | 5 | attr_reader :business 6 | attr_reader :commercial 7 | attr_reader :consumer 8 | attr_reader :corporate 9 | attr_reader :country_of_issuance 10 | attr_reader :debit 11 | attr_reader :durbin_regulated 12 | attr_reader :healthcare 13 | attr_reader :issuing_bank 14 | attr_reader :payroll 15 | attr_reader :prepaid 16 | attr_reader :prepaid_reloadable 17 | attr_reader :product_id 18 | attr_reader :purchase 19 | 20 | def initialize(attributes) 21 | set_instance_variables_from_hash attributes unless attributes.nil? 22 | end 23 | 24 | def inspect 25 | formatted_attributes = self.class._attributes.map do |attr| 26 | "#{attr}: #{send(attr).inspect}" 27 | end 28 | "#<#{self.class} #{formatted_attributes.join(", ")}>" 29 | end 30 | 31 | def self._attributes 32 | [ 33 | :business, :commercial, :consumer, :corporate, :country_of_issuance, :debit, 34 | :durbin_regulated, :healthcare, :issuing_bank, :payroll, :prepaid, 35 | :prepaid_reloadable, :product_id, :purchase 36 | ] 37 | end 38 | end 39 | end 40 | -------------------------------------------------------------------------------- /lib/braintree/client_token.rb: -------------------------------------------------------------------------------- 1 | require "json" 2 | 3 | module Braintree 4 | module ClientToken 5 | DEFAULT_VERSION = 2 6 | 7 | def self.generate(*args) 8 | Configuration.gateway.client_token.generate(*args) 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /lib/braintree/client_token_gateway.rb: -------------------------------------------------------------------------------- 1 | module Braintree 2 | class ClientTokenGateway 3 | include BaseModule 4 | 5 | def initialize(gateway) 6 | @gateway = gateway 7 | @config = gateway.config 8 | @config.assert_has_access_token_or_keys 9 | end 10 | 11 | def generate(options={}) 12 | _validate_options(options) 13 | 14 | options[:version] ||= ClientToken::DEFAULT_VERSION 15 | 16 | Util.verify_keys(ClientTokenGateway._generate_signature, options) 17 | 18 | params = {:client_token => options} 19 | result = @config.http.post("#{@config.base_merchant_path}/client_token", params) 20 | 21 | if result[:client_token] 22 | result[:client_token][:value] 23 | else 24 | raise ArgumentError, result[:api_error_response][:message] 25 | end 26 | end 27 | 28 | def self._generate_signature 29 | [ 30 | :address_id, :customer_id, :proxy_merchant_id, :merchant_account_id, 31 | :version, 32 | {:domains => [:_any_key_]}, 33 | {:options => [:fail_on_duplicate_payment_method, :fail_on_duplicate_payment_method_for_customer, :make_default, :verify_card]} 34 | ] 35 | end 36 | 37 | def _validate_options(options) 38 | [:fail_on_duplicate_payment_method, :fail_on_duplicate_payment_method_for_customer, :make_default, :verify_card].each do |credit_card_option| 39 | if options[credit_card_option] 40 | raise ArgumentError.new("cannot specify #{credit_card_option} without a customer_id") unless options[:customer_id] 41 | end 42 | end 43 | end 44 | end 45 | end 46 | -------------------------------------------------------------------------------- /lib/braintree/connected_merchant_paypal_status_changed.rb: -------------------------------------------------------------------------------- 1 | module Braintree 2 | class ConnectedMerchantPayPalStatusChanged 3 | include BaseModule 4 | 5 | attr_reader :action 6 | attr_reader :merchant_public_id 7 | attr_reader :oauth_application_client_id 8 | 9 | alias_method :merchant_id, :merchant_public_id 10 | 11 | def initialize(attributes) 12 | set_instance_variables_from_hash(attributes) 13 | end 14 | 15 | class << self 16 | protected :new 17 | def _new(*args) 18 | self.new(*args) 19 | end 20 | end 21 | end 22 | end 23 | -------------------------------------------------------------------------------- /lib/braintree/connected_merchant_status_transitioned.rb: -------------------------------------------------------------------------------- 1 | module Braintree 2 | class ConnectedMerchantStatusTransitioned 3 | include BaseModule 4 | 5 | attr_reader :merchant_public_id 6 | attr_reader :oauth_application_client_id 7 | attr_reader :status 8 | 9 | alias_method :merchant_id, :merchant_public_id 10 | 11 | def initialize(attributes) 12 | set_instance_variables_from_hash(attributes) 13 | end 14 | 15 | class << self 16 | protected :new 17 | def _new(*args) 18 | self.new(*args) 19 | end 20 | end 21 | end 22 | end 23 | -------------------------------------------------------------------------------- /lib/braintree/credit_card_verification_search.rb: -------------------------------------------------------------------------------- 1 | module Braintree 2 | class CreditCardVerificationSearch < AdvancedSearch 3 | text_fields( 4 | :billing_address_details_postal_code, 5 | :credit_card_cardholder_name, 6 | :customer_email, 7 | :customer_id, 8 | :id, 9 | :payment_method_token, 10 | ) 11 | 12 | equality_fields :credit_card_expiration_date 13 | partial_match_fields :credit_card_number 14 | 15 | multiple_value_field :credit_card_card_type, :allows => CreditCard::CardType::All 16 | multiple_value_field :status, :allows => CreditCardVerification::Status::All 17 | multiple_value_field :ids 18 | range_fields :created_at 19 | end 20 | end 21 | -------------------------------------------------------------------------------- /lib/braintree/customer_search.rb: -------------------------------------------------------------------------------- 1 | module Braintree 2 | class CustomerSearch < AdvancedSearch 3 | text_fields( 4 | :address_country_name, 5 | :address_extended_address, 6 | :address_first_name, 7 | :address_last_name, 8 | :address_locality, 9 | :address_postal_code, 10 | :address_region, 11 | :address_street_address, 12 | :cardholder_name, 13 | :company, 14 | :email, 15 | :fax, 16 | :first_name, 17 | :id, 18 | :last_name, 19 | :payment_method_token, 20 | :paypal_account_email, 21 | :phone, 22 | :website, 23 | ) 24 | 25 | is_fields :payment_method_token_with_duplicates 26 | 27 | equality_fields :credit_card_expiration_date 28 | 29 | partial_match_fields :credit_card_number 30 | 31 | multiple_value_field :ids 32 | 33 | range_fields :created_at 34 | end 35 | end 36 | -------------------------------------------------------------------------------- /lib/braintree/descriptor.rb: -------------------------------------------------------------------------------- 1 | module Braintree 2 | class Descriptor 3 | include BaseModule 4 | 5 | attr_reader :name 6 | attr_reader :phone 7 | attr_reader :url 8 | 9 | def initialize(attributes) 10 | set_instance_variables_from_hash attributes unless attributes.nil? 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /lib/braintree/digest.rb: -------------------------------------------------------------------------------- 1 | module Braintree 2 | module Digest 3 | def self.hexdigest(private_key, string) 4 | _hmac_sha1(private_key, string) 5 | end 6 | 7 | def self.secure_compare(left, right) 8 | return false unless left && right 9 | 10 | left_bytes = left.unpack("C*") 11 | right_bytes = right.unpack("C*") 12 | return false if left_bytes.size != right_bytes.size 13 | 14 | result = 0 15 | left_bytes.zip(right_bytes).each do |left_byte, right_byte| 16 | result |= left_byte ^ right_byte 17 | end 18 | result == 0 19 | end 20 | 21 | def self._hmac_sha1(key, message) 22 | key_digest = ::Digest::SHA1.digest(key) 23 | sha1 = OpenSSL::Digest.new("sha1") 24 | OpenSSL::HMAC.hexdigest(sha1, key_digest, message.to_s) 25 | end 26 | end 27 | end 28 | -------------------------------------------------------------------------------- /lib/braintree/disbursement.rb: -------------------------------------------------------------------------------- 1 | module Braintree 2 | class Disbursement 3 | include BaseModule 4 | 5 | module Types 6 | Credit = "credit" 7 | Debit = "debit" 8 | end 9 | 10 | attr_reader :amount 11 | attr_reader :disbursement_date 12 | attr_reader :disbursement_type 13 | attr_reader :exception_message 14 | attr_reader :follow_up_action 15 | attr_reader :id 16 | attr_reader :merchant_account 17 | attr_reader :retry 18 | attr_reader :success 19 | attr_reader :transaction_ids 20 | 21 | alias_method :success?, :success 22 | 23 | def initialize(gateway, attributes) 24 | @gateway = gateway 25 | set_instance_variables_from_hash(attributes) 26 | @amount = Util.to_big_decimal(amount) 27 | @disbursement_date = Date.parse(disbursement_date) 28 | @merchant_account = MerchantAccount._new(gateway, @merchant_account) 29 | end 30 | 31 | def transactions 32 | @gateway.transaction.search do |search| 33 | search.ids.in transaction_ids 34 | end 35 | end 36 | 37 | def inspect 38 | nice_attributes = self.class._inspect_attributes.map { |attr| "#{attr}: #{send(attr).inspect}" } 39 | nice_attributes << "amount: #{self.amount.to_s("F").inspect}" 40 | nice_attributes << "disbursement_date: #{self.disbursement_date}" 41 | "#<#{self.class} #{nice_attributes.join(', ')}>" 42 | end 43 | 44 | def debit? 45 | disbursement_type == Types::Debit 46 | end 47 | 48 | def credit? 49 | disbursement_type == Types::Credit 50 | end 51 | 52 | class << self 53 | protected :new 54 | def _new(*args) 55 | self.new(*args) 56 | end 57 | end 58 | 59 | def self._inspect_attributes 60 | [:id, :exception_message, :follow_up_action, :merchant_account, :transaction_ids, :retry, :success] 61 | end 62 | end 63 | end 64 | -------------------------------------------------------------------------------- /lib/braintree/discount.rb: -------------------------------------------------------------------------------- 1 | module Braintree 2 | class Discount < Modification 3 | 4 | def self.all 5 | Configuration.gateway.discount.all 6 | end 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /lib/braintree/discount_gateway.rb: -------------------------------------------------------------------------------- 1 | module Braintree 2 | class DiscountGateway 3 | def initialize(gateway) 4 | @gateway = gateway 5 | @config = gateway.config 6 | @config.assert_has_access_token_or_keys 7 | end 8 | 9 | def all 10 | response = @config.http.get("#{@config.base_merchant_path}/discounts") 11 | attributes_collection = response[:discounts] 12 | attributes_collection.map do |attributes| 13 | Discount._new(attributes) 14 | end 15 | end 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /lib/braintree/dispute/evidence.rb: -------------------------------------------------------------------------------- 1 | module Braintree 2 | class Dispute 3 | class Evidence 4 | include BaseModule 5 | 6 | attr_reader :category, 7 | :comment, 8 | :created_at, 9 | :id, 10 | :sent_to_processor_at, 11 | :url, 12 | :tag, 13 | :sequence_number 14 | 15 | def initialize(attributes) 16 | unless attributes.nil? 17 | @tag = attributes[:category] 18 | set_instance_variables_from_hash attributes 19 | end 20 | @sent_to_processor_at = Date.parse(sent_to_processor_at) unless sent_to_processor_at.nil? 21 | end 22 | end 23 | end 24 | end 25 | -------------------------------------------------------------------------------- /lib/braintree/dispute/paypal_message.rb: -------------------------------------------------------------------------------- 1 | module Braintree 2 | class Dispute 3 | class PayPalMessage 4 | include BaseModule 5 | 6 | attr_reader :message, 7 | :sender, 8 | :sent_at 9 | 10 | def initialize(attributes) 11 | set_instance_variables_from_hash attributes unless attributes.nil? 12 | end 13 | end 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /lib/braintree/dispute/status_history.rb: -------------------------------------------------------------------------------- 1 | module Braintree 2 | class Dispute 3 | class StatusHistory 4 | include BaseModule 5 | 6 | attr_reader :disbursement_date 7 | attr_reader :effective_date 8 | attr_reader :status 9 | attr_reader :timestamp 10 | 11 | def initialize(attributes) 12 | set_instance_variables_from_hash attributes unless attributes.nil? 13 | @disbursement_date = Date.parse(disbursement_date) unless disbursement_date.nil? 14 | @effective_date = Date.parse(effective_date) unless effective_date.nil? 15 | end 16 | end 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /lib/braintree/dispute/transaction.rb: -------------------------------------------------------------------------------- 1 | module Braintree 2 | class Dispute 3 | class Transaction 4 | include BaseModule 5 | 6 | attr_reader :amount 7 | attr_reader :created_at 8 | attr_reader :id 9 | attr_reader :installment_count 10 | attr_reader :order_id 11 | attr_reader :purchase_order_number 12 | attr_reader :payment_instrument_subtype 13 | 14 | def initialize(attributes) 15 | set_instance_variables_from_hash attributes unless attributes.nil? 16 | @amount = Util.to_big_decimal(amount) 17 | end 18 | end 19 | end 20 | end 21 | -------------------------------------------------------------------------------- /lib/braintree/dispute/transaction_details.rb: -------------------------------------------------------------------------------- 1 | module Braintree 2 | class Dispute 3 | class TransactionDetails 4 | include BaseModule 5 | 6 | attr_reader :amount 7 | attr_reader :id 8 | 9 | def initialize(attributes) 10 | set_instance_variables_from_hash attributes unless attributes.nil? 11 | @amount = Util.to_big_decimal(amount) 12 | end 13 | end 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /lib/braintree/dispute_search.rb: -------------------------------------------------------------------------------- 1 | module Braintree 2 | class DisputeSearch < AdvancedSearch 3 | text_fields( 4 | :case_number, 5 | :customer_id, 6 | :id, 7 | :reference_number, 8 | :transaction_id, 9 | ) 10 | # NEXT_MAJOR_VERSION Remove this attribute 11 | # DEPRECATED The chargeback_protection_level attribute is deprecated in favor of protection_level 12 | multiple_value_field :chargeback_protection_level, :allows => Dispute::ChargebackProtectionLevel::All 13 | multiple_value_field :protection_level, :allows => Dispute::ProtectionLevel::All 14 | multiple_value_field :kind, :allows => Dispute::Kind::All 15 | multiple_value_field :merchant_account_id 16 | multiple_value_field :pre_dispute_program, :allows => Dispute::PreDisputeProgram::All 17 | multiple_value_field :reason, :allows => Dispute::Reason::All 18 | multiple_value_field :reason_code 19 | multiple_value_field :status, :allows => Dispute::Status::All 20 | multiple_value_field :transaction_source 21 | 22 | range_fields( 23 | :amount_disputed, 24 | :amount_won, 25 | :disbursement_date, 26 | :effective_date, 27 | :received_date, 28 | :reply_by_date, 29 | ) 30 | end 31 | end 32 | -------------------------------------------------------------------------------- /lib/braintree/document_upload.rb: -------------------------------------------------------------------------------- 1 | module Braintree 2 | class DocumentUpload 3 | include BaseModule 4 | include Braintree::Util::IdEquality 5 | 6 | module Kind 7 | IdentityDocument = "identity_document" 8 | EvidenceDocument = "evidence_document" 9 | PayoutInvoiceDocument = "payout_invoice_document" 10 | end 11 | 12 | attr_reader :content_type 13 | attr_reader :id 14 | attr_reader :kind 15 | attr_reader :name 16 | attr_reader :size 17 | 18 | def self.create(*args) 19 | Configuration.gateway.document_upload.create(*args) 20 | end 21 | 22 | def self.create!(*args) 23 | Configuration.gateway.document_upload.create!(*args) 24 | end 25 | 26 | def initialize(attributes) 27 | set_instance_variables_from_hash(attributes) 28 | end 29 | 30 | class << self 31 | protected :new 32 | def _new(*args) 33 | self.new(*args) 34 | end 35 | end 36 | end 37 | end 38 | -------------------------------------------------------------------------------- /lib/braintree/document_upload_gateway.rb: -------------------------------------------------------------------------------- 1 | module Braintree 2 | class DocumentUploadGateway 3 | include BaseModule 4 | 5 | def initialize(gateway) 6 | @gateway = gateway 7 | @config = gateway.config 8 | @config.assert_has_access_token_or_keys 9 | end 10 | 11 | def create(attributes) 12 | Util.verify_keys(DocumentUploadGateway._create_signature, attributes) 13 | _do_create "/document_uploads", {"document_upload[kind]" => attributes[:kind]}, attributes[:file] 14 | end 15 | 16 | def create!(*args) 17 | return_object_or_raise(:document_upload) { create(*args) } 18 | end 19 | 20 | def self._create_signature 21 | [ 22 | :kind, 23 | :file 24 | ] 25 | end 26 | 27 | def _do_create(path, params, file) 28 | response = @config.http.post("#{@config.base_merchant_path}#{path}", params, file) 29 | if response[:document_upload] 30 | SuccessfulResult.new(:document_upload => DocumentUpload._new(response[:document_upload])) 31 | elsif response[:api_error_response] 32 | ErrorResult.new(@gateway, response[:api_error_response]) 33 | else 34 | raise UnexpectedError, "expected :document_upload or :api_error_response" 35 | end 36 | end 37 | end 38 | end 39 | -------------------------------------------------------------------------------- /lib/braintree/enriched_customer_data.rb: -------------------------------------------------------------------------------- 1 | module Braintree 2 | class EnrichedCustomerData 3 | include BaseModule 4 | 5 | attr_reader :fields_updated 6 | attr_reader :profile_data 7 | 8 | def initialize(attributes) 9 | set_instance_variables_from_hash(attributes) 10 | @profile_data = VenmoProfileData._new(attributes[:profile_data]) 11 | end 12 | 13 | class << self 14 | protected :new 15 | end 16 | 17 | def self._new(*args) 18 | self.new(*args) 19 | end 20 | end 21 | end 22 | -------------------------------------------------------------------------------- /lib/braintree/error_result.rb: -------------------------------------------------------------------------------- 1 | module Braintree 2 | class ErrorResult 3 | 4 | attr_reader :credit_card_verification 5 | attr_reader :errors 6 | attr_reader :merchant_account 7 | attr_reader :message 8 | attr_reader :params 9 | attr_reader :subscription 10 | attr_reader :transaction 11 | attr_reader :verification 12 | 13 | def initialize(gateway, data) 14 | @gateway = gateway 15 | @params = data[:params] if data[:params] 16 | @credit_card_verification = CreditCardVerification._new(data[:verification]) if data[:verification] 17 | @merchant_account = MerchantAccount._new(gateway, data[:merchant_account]) if data[:merchant_account] 18 | @message = data[:message] 19 | @transaction = Transaction._new(gateway, data[:transaction]) if data[:transaction] 20 | @verification = CreditCardVerification._new(data[:verification]) if data[:verification] 21 | @subscription = Subscription._new(gateway, data[:subscription]) if data[:subscription] 22 | @errors = Errors.new(data[:errors]) 23 | end 24 | 25 | def inspect 26 | if @credit_card_verification 27 | verification_inspect = " credit_card_verification: #{@credit_card_verification.inspect}" 28 | end 29 | if @transaction 30 | transaction_inspect = " transaction: #{@transaction.inspect}" 31 | end 32 | "#<#{self.class} params:{...} errors:<#{@errors._inner_inspect}>#{verification_inspect}#{transaction_inspect}>" 33 | end 34 | 35 | def success? 36 | false 37 | end 38 | end 39 | end 40 | -------------------------------------------------------------------------------- /lib/braintree/errors.rb: -------------------------------------------------------------------------------- 1 | module Braintree 2 | class Errors 3 | include Enumerable 4 | 5 | def initialize(data = {}) 6 | data = data.merge(:errors => []) unless data 7 | @errors = ValidationErrorCollection.new(data) 8 | end 9 | 10 | def each(&block) 11 | @errors.deep_errors.each(&block) 12 | end 13 | 14 | def for(scope) 15 | @errors.for(scope) 16 | end 17 | 18 | def inspect 19 | "#<#{self.class} #{_inner_inspect}>" 20 | end 21 | 22 | # Returns the total number of validation errors at all levels of nesting. For example, 23 | # if creating a customer with a credit card and a billing address, and each of the customer, 24 | # credit card, and billing address has 1 error, this method will return 3. 25 | def size 26 | @errors.deep_size 27 | end 28 | 29 | def _inner_inspect 30 | @errors._inner_inspect 31 | end 32 | end 33 | end 34 | 35 | -------------------------------------------------------------------------------- /lib/braintree/exceptions.rb: -------------------------------------------------------------------------------- 1 | module Braintree 2 | class BraintreeError < ::StandardError; end 3 | 4 | class AuthenticationError < BraintreeError; end 5 | 6 | class AuthorizationError < BraintreeError; end 7 | 8 | class ConfigurationError < BraintreeError; end 9 | 10 | class GatewayTimeoutError < BraintreeError; end 11 | 12 | class InvalidSignature < BraintreeError; end 13 | 14 | class InvalidChallenge < BraintreeError; end 15 | 16 | class NotFoundError < BraintreeError; end 17 | 18 | class RequestTimeoutError < BraintreeError; end 19 | 20 | class ServerError < BraintreeError; end 21 | 22 | class ServiceUnavailableError < BraintreeError; end 23 | 24 | class SSLCertificateError < BraintreeError; end 25 | 26 | class TooManyRequestsError < BraintreeError; end 27 | 28 | class UnexpectedError < BraintreeError; end 29 | 30 | class UpgradeRequiredError < BraintreeError; end 31 | 32 | class ValidationsFailed < BraintreeError 33 | attr_reader :error_result 34 | 35 | def initialize(error_result) 36 | @error_result = error_result 37 | end 38 | 39 | def inspect 40 | "#<#{self.class} error_result: #{@error_result.inspect}>" 41 | end 42 | 43 | def to_s 44 | inspect 45 | end 46 | end 47 | 48 | class TestOperationPerformedInProduction < BraintreeError; end 49 | end 50 | 51 | -------------------------------------------------------------------------------- /lib/braintree/exchange_rate.rb: -------------------------------------------------------------------------------- 1 | module Braintree 2 | class ExchangeRate 3 | include BaseModule 4 | 5 | def initialize(gateway, attributes) 6 | set_instance_variables_from_hash(attributes) 7 | end 8 | 9 | def self.generate(exchange_rate_quote_request) 10 | Configuration.gateway.exchange_rate_quote.generate(exchange_rate_quote_request) 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /lib/braintree/exchange_rate_quote.rb: -------------------------------------------------------------------------------- 1 | module Braintree 2 | class ExchangeRateQuote 3 | include BaseModule 4 | 5 | attr_reader :attrs 6 | attr_reader :base_amount 7 | attr_reader :exchange_rate 8 | attr_reader :expires_at 9 | attr_reader :id 10 | attr_reader :quote_amount 11 | attr_reader :refreshes_at 12 | attr_reader :trade_rate 13 | 14 | def initialize(attributes) 15 | @attrs = attributes.keys 16 | set_instance_variables_from_hash(attributes) 17 | end 18 | 19 | def inspect 20 | inspected_attributes = @attrs.map { |attr| "#{attr}:#{send(attr).inspect}" } 21 | "#<#{self.class} #{inspected_attributes.join(" ")}>" 22 | end 23 | end 24 | end 25 | -------------------------------------------------------------------------------- /lib/braintree/exchange_rate_quote_gateway.rb: -------------------------------------------------------------------------------- 1 | module Braintree 2 | class ExchangeRateQuoteGateway 3 | def initialize(gateway) 4 | @gateway = gateway 5 | end 6 | 7 | DEFINITION = <<-GRAPHQL 8 | mutation GenerateExchangeRateQuoteInput($input: GenerateExchangeRateQuoteInput!) { 9 | generateExchangeRateQuote(input: $input) { 10 | quotes { 11 | id 12 | baseAmount {value, currencyCode} 13 | quoteAmount {value, currencyCode} 14 | exchangeRate 15 | tradeRate 16 | expiresAt 17 | refreshesAt 18 | } 19 | } 20 | } 21 | GRAPHQL 22 | 23 | def generate(params) 24 | response = @gateway.config.graphql_client.query(DEFINITION, {input: params}) 25 | 26 | if response.has_key?(:data) && response[:data][:generateExchangeRateQuote] 27 | response[:data][:generateExchangeRateQuote] 28 | elsif response[:errors] 29 | ErrorResult.new(@gateway, response[:errors]) 30 | else 31 | raise UnexpectedError, "expected :generateExchangeRateQuote or :api_error_response in GraphQL response" 32 | end 33 | end 34 | end 35 | end 36 | -------------------------------------------------------------------------------- /lib/braintree/exchange_rate_quote_input.rb: -------------------------------------------------------------------------------- 1 | module Braintree 2 | class ExchangeRateQuoteInput 3 | include BaseModule 4 | 5 | attr_reader :attrs 6 | attr_reader :base_currency 7 | attr_reader :base_amount 8 | attr_reader :markup 9 | attr_reader :quote_currency 10 | 11 | def initialize(attributes) 12 | @attrs = attributes.keys 13 | set_instance_variables_from_hash(attributes) 14 | end 15 | 16 | def inspect 17 | inspected_attributes = @attrs.map { |attr| "#{attr}:#{send(attr).inspect}" } 18 | "#<#{self.class} #{inspected_attributes.join(" ")}>" 19 | end 20 | end 21 | end 22 | -------------------------------------------------------------------------------- /lib/braintree/exchange_rate_quote_request.rb: -------------------------------------------------------------------------------- 1 | module Braintree 2 | class ExchangeRateQuoteRequest 3 | include BaseModule 4 | 5 | attr_reader :quotes 6 | 7 | def initialize(attributes) 8 | @attrs = attributes.keys 9 | set_instance_variables_from_hash(attributes) 10 | @quotes = (@quotes || []).map { |quote_hash| ExchangeRateQuoteInput.new(quote_hash) } 11 | end 12 | 13 | def inspect 14 | inspected_attributes = @attrs.map { |attr| "#{attr}:#{send(attr).inspect}" } 15 | "#<#{self.class} #{inspected_attributes.join(" ")}>" 16 | end 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /lib/braintree/exchange_rate_quote_response.rb: -------------------------------------------------------------------------------- 1 | module Braintree 2 | class ExchangeRateQuoteResponse 3 | include BaseModule 4 | 5 | attr_reader :quotes 6 | 7 | def initialize(attributes) 8 | @attrs = attributes.keys 9 | set_instance_variables_from_hash(attributes) 10 | @quotes = (@quotes || []).map { |quote_hash| ExchangeRateQuote.new(quote_hash) } 11 | end 12 | 13 | def inspect 14 | inspected_attributes = @attrs.map { |attr| "#{attr}:#{send(attr).inspect}" } 15 | "#<#{self.class} #{inspected_attributes.join(" ")}>" 16 | end 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /lib/braintree/facilitated_details.rb: -------------------------------------------------------------------------------- 1 | module Braintree 2 | class FacilitatedDetails 3 | include BaseModule 4 | 5 | attr_reader :merchant_id 6 | attr_reader :merchant_name 7 | attr_reader :payment_method_nonce 8 | 9 | def initialize(attributes) 10 | set_instance_variables_from_hash attributes unless attributes.nil? 11 | end 12 | 13 | def inspect 14 | attr_order = [:merchant_id, :merchant_name, :payment_method_nonce] 15 | formatted_attrs = attr_order.map do |attr| 16 | "#{attr}: #{send(attr).inspect}" 17 | end 18 | "#" 19 | end 20 | end 21 | end 22 | -------------------------------------------------------------------------------- /lib/braintree/facilitator_details.rb: -------------------------------------------------------------------------------- 1 | module Braintree 2 | class FacilitatorDetails 3 | include BaseModule 4 | 5 | attr_reader :oauth_application_client_id 6 | attr_reader :oauth_application_name 7 | 8 | def initialize(attributes) 9 | set_instance_variables_from_hash attributes unless attributes.nil? 10 | end 11 | 12 | def inspect 13 | attr_order = [:oauth_application_client_id, :oauth_application_name] 14 | formatted_attrs = attr_order.map do |attr| 15 | "#{attr}: #{send(attr).inspect}" 16 | end 17 | "#" 18 | end 19 | end 20 | end 21 | -------------------------------------------------------------------------------- /lib/braintree/google_pay_card.rb: -------------------------------------------------------------------------------- 1 | module Braintree 2 | class GooglePayCard 3 | include BaseModule 4 | 5 | attr_reader :bin 6 | attr_reader :business 7 | attr_reader :commercial 8 | attr_reader :consumer 9 | attr_reader :corporate 10 | attr_reader :country_of_issuance 11 | attr_reader :created_at 12 | attr_reader :customer_id 13 | attr_reader :debit 14 | attr_reader :default 15 | attr_reader :durbin_regulated 16 | attr_reader :expiration_month 17 | attr_reader :expiration_year 18 | attr_reader :google_transaction_id 19 | attr_reader :healthcare 20 | attr_reader :image_url 21 | attr_reader :issuing_bank 22 | attr_reader :payroll 23 | attr_reader :prepaid 24 | attr_reader :prepaid_reloadable 25 | attr_reader :product_id 26 | attr_reader :purchase 27 | attr_reader :source_card_last_4 28 | attr_reader :source_card_type 29 | attr_reader :source_description 30 | attr_reader :subscriptions 31 | attr_reader :token 32 | attr_reader :updated_at 33 | attr_reader :virtual_card_last_4 34 | attr_reader :virtual_card_type 35 | 36 | def initialize(gateway, attributes) 37 | @gateway = gateway 38 | set_instance_variables_from_hash(attributes) 39 | @subscriptions = (@subscriptions || []).map { |subscription_hash| Subscription._new(@gateway, subscription_hash) } 40 | end 41 | 42 | def default? 43 | @default 44 | end 45 | 46 | def is_network_tokenized? 47 | @is_network_tokenized 48 | end 49 | 50 | def card_type 51 | virtual_card_type 52 | end 53 | 54 | def last_4 55 | virtual_card_last_4 56 | end 57 | 58 | class << self 59 | protected :new 60 | end 61 | 62 | def self._new(*args) 63 | self.new(*args) 64 | end 65 | end 66 | end 67 | -------------------------------------------------------------------------------- /lib/braintree/granted_payment_instrument_update.rb: -------------------------------------------------------------------------------- 1 | module Braintree 2 | class GrantedPaymentInstrumentUpdate 3 | include BaseModule 4 | 5 | attr_reader :grant_owner_merchant_id 6 | attr_reader :grant_recipient_merchant_id 7 | attr_reader :payment_method_nonce 8 | attr_reader :token 9 | attr_reader :updated_fields 10 | 11 | def initialize(attributes) 12 | set_instance_variables_from_hash(attributes) 13 | @payment_method_nonce = attributes[:payment_method_nonce][:nonce] 14 | end 15 | 16 | class << self 17 | protected :new 18 | def _new(*args) 19 | self.new(*args) 20 | end 21 | end 22 | end 23 | end 24 | -------------------------------------------------------------------------------- /lib/braintree/graphql/enums/recommendations.rb: -------------------------------------------------------------------------------- 1 | # Represents available types of customer recommendations that can be retrieved using a PayPal customer session. 2 | 3 | #Experimental 4 | # This enum is experimental and may change in future releases. 5 | module Braintree 6 | module Recommendations 7 | PAYMENT_RECOMMENDATIONS = "PAYMENT_RECOMMENDATIONS" 8 | end 9 | end -------------------------------------------------------------------------------- /lib/braintree/graphql/enums/recommended_payment_option.rb: -------------------------------------------------------------------------------- 1 | # Represents available payment options related to PayPal customer session recommendations. 2 | 3 | #Experimental 4 | # This enum is experimental and may change in future releases. 5 | module Braintree 6 | module RecommendedPaymentOption 7 | PAYPAL = "PAYPAL" 8 | VENMO = "VENMO" 9 | end 10 | end -------------------------------------------------------------------------------- /lib/braintree/graphql/inputs/create_customer_session_input.rb: -------------------------------------------------------------------------------- 1 | # Represents the input to request the creation of a PayPal customer session. 2 | 3 | #Experimental 4 | # This class is experimental and may change in future releases. 5 | module Braintree 6 | class CreateCustomerSessionInput 7 | include BaseModule 8 | 9 | attr_reader :attrs 10 | attr_reader :merchant_account_id 11 | attr_reader :session_id 12 | attr_reader :customer 13 | attr_reader :domain 14 | attr_reader :purchase_units 15 | 16 | def initialize(attributes) 17 | @attrs = attributes.keys 18 | set_instance_variables_from_hash(attributes) 19 | @customer = attributes[:customer] ? CustomerSessionInput.new(attributes[:customer]) : nil 20 | if attributes[:purchase_units] 21 | @purchase_units = attributes[:purchase_units].map do |unit| 22 | PayPalPurchaseUnitInput.new(unit) 23 | end 24 | end 25 | end 26 | 27 | def inspect 28 | inspected_attributes = @attrs.map { |attr| "#{attr}:#{send(attr).inspect}" } 29 | "#<#{self.class} #{inspected_attributes.join(" ")}>" 30 | end 31 | 32 | def to_graphql_variables 33 | variables = {} 34 | variables["merchantAccountId"] = merchant_account_id if merchant_account_id 35 | variables["sessionId"] = session_id if session_id 36 | variables["domain"] = domain if domain 37 | variables["customer"] = customer.to_graphql_variables if customer 38 | variables["purchaseUnits"] = purchase_units.map(&:to_graphql_variables) if purchase_units 39 | variables 40 | end 41 | end 42 | end 43 | 44 | 45 | -------------------------------------------------------------------------------- /lib/braintree/graphql/inputs/customer_recommendations_input.rb: -------------------------------------------------------------------------------- 1 | # Represents the input to request PayPal customer session recommendations. 2 | 3 | #Experimental 4 | # This class is experimental and may change in future releases. 5 | module Braintree 6 | class CustomerRecommendationsInput 7 | include BaseModule 8 | 9 | attr_reader :attrs 10 | attr_reader :merchant_account_id 11 | attr_reader :session_id 12 | attr_reader :customer 13 | attr_reader :purchase_units 14 | attr_reader :domain 15 | 16 | def initialize(attributes) 17 | @attrs = attributes.keys 18 | set_instance_variables_from_hash(attributes) 19 | @customer = attributes[:customer] ? CustomerSessionInput.new(attributes[:customer]) : nil 20 | @purchase_units = attributes[:purchase_units] ? attributes[:purchase_units].map { |pu| PayPalPurchaseUnitInput.new(pu) } : nil 21 | end 22 | 23 | def inspect 24 | inspected_attributes = @attrs.map { |attr| "#{attr}:#{send(attr).inspect}" } 25 | "#<#{self.class} #{inspected_attributes.join(" ")}>" 26 | end 27 | 28 | def to_graphql_variables 29 | variables = {} 30 | variables["merchantAccountId"] = merchant_account_id if merchant_account_id 31 | variables["sessionId"] = session_id if session_id 32 | variables["customer"] = customer.to_graphql_variables if customer 33 | variables["domain"] = domain if domain 34 | variables["purchaseUnits"] = purchase_units.map(&:to_graphql_variables) if purchase_units 35 | variables 36 | end 37 | end 38 | end 39 | 40 | 41 | -------------------------------------------------------------------------------- /lib/braintree/graphql/inputs/customer_session_input.rb: -------------------------------------------------------------------------------- 1 | # Customer identifying information for a PayPal customer session. 2 | 3 | #Experimental 4 | # This class is experimental and may change in future releases. 5 | module Braintree 6 | class CustomerSessionInput 7 | include BaseModule 8 | 9 | attr_reader :attrs 10 | attr_reader :email 11 | attr_reader :hashed_email 12 | attr_reader :phone 13 | attr_reader :hashed_phone 14 | attr_reader :device_fingerprint_id 15 | attr_reader :paypal_app_installed 16 | attr_reader :venmo_app_installed 17 | attr_reader :user_agent 18 | 19 | def initialize(attributes) 20 | @attrs = attributes.keys 21 | set_instance_variables_from_hash(attributes) 22 | @phone = attributes[:phone] ? PhoneInput.new(attributes[:phone]) : nil 23 | end 24 | 25 | def inspect 26 | inspected_attributes = @attrs.map { |attr| "#{attr}:#{send(attr).inspect}" } 27 | "#<#{self.class} #{inspected_attributes.join(" ")}>" 28 | end 29 | 30 | def to_graphql_variables 31 | variables = {} 32 | variables["email"] = email if email 33 | variables["hashedEmail"] = hashed_email if hashed_email 34 | variables["phone"] = phone.to_graphql_variables if phone 35 | variables["hashedPhone"] = hashed_phone if hashed_phone 36 | variables["deviceFingerprintId"] = device_fingerprint_id if device_fingerprint_id 37 | variables["paypalAppInstalled"] = paypal_app_installed if paypal_app_installed 38 | variables["venmoAppInstalled"] = venmo_app_installed if venmo_app_installed 39 | variables["userAgent"] = user_agent if user_agent 40 | variables 41 | end 42 | end 43 | end 44 | 45 | 46 | -------------------------------------------------------------------------------- /lib/braintree/graphql/inputs/monetary_amount_input.rb: -------------------------------------------------------------------------------- 1 | #Experimental 2 | # This class is experimental and may change in future releases. 3 | module Braintree 4 | class MonetaryAmountInput 5 | include BaseModule 6 | 7 | attr_reader :attrs 8 | attr_reader :value 9 | attr_reader :currency_code 10 | 11 | def initialize(attributes) 12 | @attrs = attributes.keys 13 | set_instance_variables_from_hash(attributes) 14 | end 15 | 16 | def inspect 17 | inspected_attributes = @attrs.map { |attr| "#{attr}:#{send(attr).inspect}" } 18 | "#<#{self.class} #{inspected_attributes.join(" ")}>" 19 | end 20 | 21 | def to_graphql_variables 22 | variables = {} 23 | variables["value"] = value if value 24 | variables["currencyCode"] = currency_code if currency_code 25 | variables 26 | end 27 | end 28 | end -------------------------------------------------------------------------------- /lib/braintree/graphql/inputs/paypal_payee_input.rb: -------------------------------------------------------------------------------- 1 | #Experimental 2 | # This class is experimental and may change in future releases. 3 | module Braintree 4 | class PayPalPayeeInput 5 | include BaseModule 6 | 7 | attr_reader :attrs 8 | attr_reader :email_address 9 | attr_reader :client_id 10 | 11 | def initialize(attributes) 12 | @attrs = attributes.keys 13 | set_instance_variables_from_hash(attributes) 14 | end 15 | 16 | def inspect 17 | inspected_attributes = @attrs.map { |attr| "#{attr}:#{send(attr).inspect}" } 18 | "#<#{self.class} #{inspected_attributes.join(" ")}>" 19 | end 20 | 21 | def to_graphql_variables 22 | variables = {} 23 | variables["emailAddress"] = email_address if email_address 24 | variables["clientId"] = client_id if client_id 25 | variables 26 | end 27 | end 28 | end -------------------------------------------------------------------------------- /lib/braintree/graphql/inputs/paypal_purchase_unit_input.rb: -------------------------------------------------------------------------------- 1 | #Experimental 2 | # This class is experimental and may change in future releases. 3 | module Braintree 4 | class PayPalPurchaseUnitInput 5 | include BaseModule 6 | 7 | attr_reader :attrs 8 | attr_reader :amount 9 | attr_reader :payee 10 | 11 | def initialize(attributes) 12 | @attrs = attributes.keys 13 | unless attributes[:amount] 14 | raise ArgumentError, "Expected hash to contain a :amount" 15 | end 16 | set_instance_variables_from_hash(attributes) 17 | @payee = attributes[:payee] ? PayPalPayeeInput.new(attributes[:payee]) : nil 18 | @amount = attributes[:amount] ? MonetaryAmountInput.new(attributes[:amount]) : nil 19 | end 20 | def inspect 21 | inspected_attributes = @attrs.map { |attr| "#{attr}:#{send(attr).inspect}" } 22 | "#<#{self.class} #{inspected_attributes.join(" ")}>" 23 | end 24 | def to_graphql_variables 25 | variables = {} 26 | variables["amount"] = amount.to_graphql_variables if amount 27 | variables["payee"] = payee.to_graphql_variables if payee 28 | variables 29 | end 30 | end 31 | end -------------------------------------------------------------------------------- /lib/braintree/graphql/inputs/phone_input.rb: -------------------------------------------------------------------------------- 1 | # Phone number input for PayPal customer session. 2 | 3 | #Experimental 4 | # This class is experimental and may change in future releases. 5 | module Braintree 6 | class PhoneInput 7 | include BaseModule 8 | 9 | attr_reader :attrs 10 | attr_reader :country_phone_code 11 | attr_reader :phone_number 12 | attr_reader :extension_number 13 | 14 | def initialize(attributes) 15 | @attrs = attributes.keys 16 | set_instance_variables_from_hash(attributes) 17 | end 18 | 19 | def inspect 20 | inspected_attributes = @attrs.map { |attr| "#{attr}:#{send(attr).inspect}" } 21 | "#<#{self.class} #{inspected_attributes.join(" ")}>" 22 | end 23 | 24 | def to_graphql_variables 25 | variables = {} 26 | variables["countryPhoneCode"] = country_phone_code if country_phone_code 27 | variables["phoneNumber"] = phone_number if phone_number 28 | variables["extensionNumber"] = extension_number if extension_number 29 | variables 30 | end 31 | end 32 | end 33 | 34 | 35 | -------------------------------------------------------------------------------- /lib/braintree/graphql/inputs/update_customer_session_input.rb: -------------------------------------------------------------------------------- 1 | # Represents the input to request an update to a PayPal customer session. 2 | 3 | #Experimental 4 | # This class is experimental and may change in future releases. 5 | module Braintree 6 | class UpdateCustomerSessionInput 7 | include BaseModule 8 | 9 | attr_reader :attrs 10 | attr_reader :merchant_account_id 11 | attr_reader :session_id 12 | attr_reader :customer 13 | attr_reader :purchase_units 14 | 15 | def initialize(attributes) 16 | unless attributes[:session_id] 17 | raise ArgumentError, "Expected hash to contain a :session_id" 18 | end 19 | @attrs = attributes.keys 20 | set_instance_variables_from_hash(attributes) 21 | @customer = attributes[:customer] ? CustomerSessionInput.new(attributes[:customer]) : nil 22 | @purchase_units = attributes[:purchase_units] ? attributes[:purchase_units].map { |pu| PayPalPurchaseUnitInput.new(pu) } : nil 23 | end 24 | 25 | def inspect 26 | inspected_attributes = @attrs.map { |attr| "#{attr}:#{send(attr).inspect}" } 27 | "#<#{self.class} #{inspected_attributes.join(" ")}>" 28 | end 29 | 30 | def to_graphql_variables 31 | variables = {} 32 | variables["merchantAccountId"] = merchant_account_id if merchant_account_id 33 | variables["sessionId"] = session_id if session_id 34 | variables["customer"] = customer.to_graphql_variables if customer 35 | variables["purchaseUnits"] = purchase_units.map(&:to_graphql_variables) if purchase_units 36 | variables 37 | end 38 | 39 | end 40 | end 41 | 42 | 43 | -------------------------------------------------------------------------------- /lib/braintree/graphql/types/payment_options.rb: -------------------------------------------------------------------------------- 1 | # Represents the payment method and priority associated with a PayPal customer session. 2 | 3 | #Experimental 4 | # This class is experimental and may change in future releases. 5 | module Braintree 6 | class PaymentOptions 7 | include BaseModule 8 | 9 | attr_reader :attrs 10 | attr_reader :payment_option 11 | attr_reader :recommended_priority 12 | 13 | def initialize(attributes) 14 | @attrs = [:payment_option, :recommended_priority] 15 | @payment_option = attributes[:paymentOption] if attributes[:paymentOption] 16 | @recommended_priority = attributes[:recommendedPriority] if attributes[:recommendedPriority] 17 | 18 | end 19 | 20 | def inspect 21 | inspected_attributes = @attrs.map { |attr| "#{attr}:#{send(attr).inspect}" } 22 | "#<#{self.class} #{inspected_attributes.join(" ")}>" 23 | end 24 | 25 | class << self 26 | protected :new 27 | end 28 | 29 | def self._new(*args) 30 | self.new(*args) 31 | end 32 | end 33 | end 34 | 35 | 36 | -------------------------------------------------------------------------------- /lib/braintree/graphql/types/payment_recommendations.rb: -------------------------------------------------------------------------------- 1 | # Represents the payment method and priority associated with a PayPal customer session. 2 | 3 | #Experimental 4 | # This class is experimental and may change in future releases. 5 | module Braintree 6 | class PaymentRecommendations 7 | include BaseModule 8 | 9 | attr_reader :attrs 10 | attr_reader :payment_option 11 | attr_reader :recommended_priority 12 | 13 | def initialize(attributes) 14 | @attrs = [:payment_option, :recommended_priority] 15 | @payment_option = attributes[:paymentOption] if attributes[:paymentOption] 16 | @recommended_priority = attributes[:recommendedPriority] if attributes[:recommendedPriority] 17 | 18 | end 19 | 20 | def inspect 21 | inspected_attributes = @attrs.map { |attr| "#{attr}:#{send(attr).inspect}" } 22 | "#<#{self.class} #{inspected_attributes.join(" ")}>" 23 | end 24 | 25 | class << self 26 | protected :new 27 | end 28 | 29 | def self._new(*args) 30 | self.new(*args) 31 | end 32 | end 33 | end 34 | 35 | 36 | -------------------------------------------------------------------------------- /lib/braintree/graphql/unions/customer_recommendations.rb: -------------------------------------------------------------------------------- 1 | # A union of all possible customer recommendations associated with a PayPal customer session. 2 | 3 | #Experimental 4 | # This class is experimental and may change in future releases. 5 | module Braintree 6 | class CustomerRecommendations 7 | include BaseModule 8 | 9 | attr_reader :payment_options, :payment_recommendations 10 | 11 | def initialize(attributes = {}) 12 | @payment_recommendations = initialize_payment_recommendations(attributes[:payment_recommendations]) 13 | 14 | # Always derive payment_options from payment_recommendations 15 | @payment_options = @payment_recommendations.map do |recommendation| 16 | PaymentOptions._new( 17 | paymentOption: recommendation.payment_option, 18 | recommendedPriority: recommendation.recommended_priority, 19 | ) 20 | end 21 | end 22 | 23 | def inspect 24 | "#<#{self.class} payment_options: #{payment_options.inspect}, payment_recommendations: #{payment_recommendations.inspect}>" 25 | end 26 | 27 | private 28 | 29 | def initialize_payment_recommendations(payment_recommendations) 30 | return [] if payment_recommendations.nil? 31 | 32 | payment_recommendations.map do |recommendation_hash| 33 | if recommendation_hash.is_a?(PaymentRecommendations) 34 | recommendation_hash 35 | else 36 | PaymentRecommendations._new(recommendation_hash) 37 | end 38 | end 39 | end 40 | 41 | class << self 42 | def _new(attributes = {}) 43 | new(attributes) 44 | end 45 | end 46 | end 47 | end -------------------------------------------------------------------------------- /lib/braintree/graphql_client.rb: -------------------------------------------------------------------------------- 1 | module Braintree 2 | class GraphQLClient < Http 3 | 4 | def initialize(config) 5 | @config = config 6 | @graphql_headers = { 7 | "Accept" => "application/json", 8 | "Braintree-Version" => @config.graphql_api_version, 9 | "Content-Type" => "application/json" 10 | } 11 | end 12 | 13 | def query(definition, variables = {}, operationName = nil) 14 | graphql_connection = _setup_connection(@config.graphql_server, @config.graphql_port) 15 | 16 | request = {} 17 | request["query"] = definition 18 | request["operationName"] = operationName if operationName 19 | request["variables"] = variables 20 | 21 | response = _http_do Net::HTTP::Post, @config.graphql_base_url, request.to_json, nil, graphql_connection, @graphql_headers 22 | data = _parse_response(response) 23 | Util.raise_exception_for_graphql_error(data) 24 | 25 | data 26 | end 27 | 28 | def _parse_response(response) 29 | body = response.body 30 | body = Zlib::GzipReader.new(StringIO.new(body)).read if response.header["Content-Encoding"] == "gzip" 31 | JSON.parse(body, :symbolize_names => true) 32 | end 33 | 34 | def self.get_validation_errors(response) 35 | return nil unless response.key?(:errors) && response[:errors].is_a?(Array) 36 | validation_errors = response[:errors].map do |error| 37 | { 38 | :attribute => "", 39 | :code => get_validation_error_code(error), 40 | :message => error[:message] 41 | } 42 | end 43 | {errors: validation_errors} 44 | end 45 | 46 | def self.get_validation_error_code(error) 47 | error[:extensions] && error[:extensions][:legacyCode] rescue nil 48 | end 49 | end 50 | end 51 | -------------------------------------------------------------------------------- /lib/braintree/local_payment_completed.rb: -------------------------------------------------------------------------------- 1 | module Braintree 2 | class LocalPaymentCompleted 3 | include BaseModule 4 | 5 | attr_reader :bic 6 | attr_reader :blik_aliases 7 | attr_reader :iban_last_chars 8 | attr_reader :payer_id 9 | attr_reader :payer_name 10 | attr_reader :payment_id 11 | attr_reader :payment_method_nonce 12 | attr_reader :transaction 13 | 14 | def initialize(attributes) 15 | set_instance_variables_from_hash(attributes) 16 | @transaction = Transaction._new(Configuration.gateway, transaction) unless transaction.nil? 17 | blik_aliases.map { |attrs| BlikAlias.new(attrs) } if blik_aliases 18 | end 19 | 20 | class << self 21 | protected :new 22 | end 23 | 24 | def self._new(*args) 25 | self.new(*args) 26 | end 27 | end 28 | end 29 | -------------------------------------------------------------------------------- /lib/braintree/local_payment_completed/blik_alias.rb: -------------------------------------------------------------------------------- 1 | module Braintree 2 | class LocalPaymentCompleted 3 | class BlikAlias 4 | include BaseModule 5 | 6 | attr_reader :key 7 | attr_reader :label 8 | 9 | def initialize(attributes) 10 | set_instance_variables_from_hash attributes unless attributes.nil? 11 | end 12 | 13 | def inspect 14 | attrs = [:key, :label] 15 | formatted_attrs = attrs.map do |attr| 16 | "#{attr}: #{send(attr).inspect}" 17 | end 18 | 19 | "#<#{formatted_attrs.join(", ")}>" 20 | end 21 | end 22 | end 23 | end 24 | -------------------------------------------------------------------------------- /lib/braintree/local_payment_expired.rb: -------------------------------------------------------------------------------- 1 | module Braintree 2 | class LocalPaymentExpired 3 | include BaseModule 4 | 5 | attr_reader :payment_id 6 | attr_reader :payment_context_id 7 | 8 | def initialize(attributes) 9 | set_instance_variables_from_hash(attributes) 10 | end 11 | 12 | class << self 13 | protected :new 14 | end 15 | 16 | def self._new(*args) 17 | self.new(*args) 18 | end 19 | end 20 | end 21 | 22 | -------------------------------------------------------------------------------- /lib/braintree/local_payment_funded.rb: -------------------------------------------------------------------------------- 1 | module Braintree 2 | class LocalPaymentFunded 3 | include BaseModule 4 | 5 | attr_reader :payment_id 6 | attr_reader :payment_context_id 7 | attr_reader :transaction 8 | 9 | def initialize(attributes) 10 | set_instance_variables_from_hash(attributes) 11 | @transaction = Transaction._new(Configuration.gateway, transaction) 12 | end 13 | 14 | class << self 15 | protected :new 16 | end 17 | 18 | def self._new(*args) 19 | self.new(*args) 20 | end 21 | end 22 | end 23 | -------------------------------------------------------------------------------- /lib/braintree/local_payment_reversed.rb: -------------------------------------------------------------------------------- 1 | module Braintree 2 | class LocalPaymentReversed 3 | include BaseModule 4 | 5 | attr_reader :payment_id 6 | 7 | def initialize(attributes) 8 | set_instance_variables_from_hash(attributes) 9 | end 10 | 11 | class << self 12 | protected :new 13 | end 14 | 15 | def self._new(*args) 16 | self.new(*args) 17 | end 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /lib/braintree/merchant.rb: -------------------------------------------------------------------------------- 1 | module Braintree 2 | class Merchant 3 | include BaseModule 4 | 5 | attr_reader :company_name 6 | attr_reader :country_code_alpha2 7 | attr_reader :country_code_alpha3 8 | attr_reader :country_code_numeric 9 | attr_reader :country_name 10 | attr_reader :email 11 | attr_reader :id 12 | attr_reader :merchant_accounts 13 | 14 | def initialize(gateway, attributes) 15 | @merchant_accounts = attributes.delete(:merchant_accounts).map do |merchant_account| 16 | MerchantAccount._new(gateway, merchant_account) 17 | end 18 | 19 | set_instance_variables_from_hash(attributes) 20 | end 21 | 22 | class << self 23 | protected :new 24 | end 25 | 26 | def self._new(*args) 27 | self.new(*args) 28 | end 29 | 30 | def self.provision_raw_apple_pay 31 | Configuration.gateway.merchant.provision_raw_apple_pay 32 | end 33 | end 34 | end 35 | -------------------------------------------------------------------------------- /lib/braintree/merchant_account.rb: -------------------------------------------------------------------------------- 1 | module Braintree 2 | class MerchantAccount 3 | include BaseModule 4 | 5 | module Status 6 | Pending = "pending" 7 | Active = "active" 8 | Suspended = "suspended" 9 | end 10 | 11 | module FundingDestination 12 | Bank = "bank" 13 | MobilePhone = "mobile_phone" 14 | Email = "email" 15 | end 16 | 17 | module FundingDestinations 18 | include Braintree::MerchantAccount::FundingDestination 19 | end 20 | 21 | attr_reader :currency_iso_code 22 | attr_reader :default 23 | attr_reader :id 24 | attr_reader :status 25 | 26 | alias_method :default?, :default 27 | 28 | def self.find(*args) 29 | Configuration.gateway.merchant_account.find(*args) 30 | end 31 | 32 | def initialize(gateway, attributes) 33 | @gateway = gateway 34 | set_instance_variables_from_hash(attributes) 35 | end 36 | 37 | class << self 38 | protected :new 39 | def _new(*args) 40 | self.new(*args) 41 | end 42 | end 43 | 44 | def inspect 45 | order = [:id, :status] 46 | nice_attributes = order.map do |attr| 47 | "#{attr}: #{send(attr).inspect}" 48 | end 49 | "#<#{self.class}: #{nice_attributes.join(', ')}>" 50 | end 51 | end 52 | end 53 | -------------------------------------------------------------------------------- /lib/braintree/merchant_account/address_details.rb: -------------------------------------------------------------------------------- 1 | module Braintree 2 | class MerchantAccount 3 | class AddressDetails 4 | include BaseModule 5 | 6 | attr_reader :locality 7 | attr_reader :postal_code 8 | attr_reader :region 9 | attr_reader :street_address 10 | 11 | def initialize(attributes) 12 | set_instance_variables_from_hash attributes unless attributes.nil? 13 | end 14 | end 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /lib/braintree/merchant_gateway.rb: -------------------------------------------------------------------------------- 1 | module Braintree 2 | class MerchantGateway 3 | def initialize(gateway) 4 | @gateway = gateway 5 | @config = gateway.config 6 | end 7 | 8 | def provision_raw_apple_pay 9 | response = @config.http.put("#{@config.base_merchant_path}/provision_raw_apple_pay") 10 | if response[:apple_pay] 11 | SuccessfulResult.new(response[:apple_pay]) 12 | elsif response[:api_error_response] 13 | ErrorResult.new(@gateway, response[:api_error_response]) 14 | else 15 | raise UnexpectedError, "expected :apple_pay or :api_error_response" 16 | end 17 | end 18 | 19 | def create(params) 20 | _create_merchant(params) 21 | end 22 | 23 | def _create_merchant(params) 24 | response = @config.http.post("/merchants/create_via_api", :merchant => params) 25 | 26 | if response.has_key?(:response) && response[:response][:merchant] 27 | Braintree::SuccessfulResult.new( 28 | :merchant => Merchant._new(@gateway, response[:response][:merchant]), 29 | :credentials => OAuthCredentials._new(response[:response][:credentials]), 30 | ) 31 | elsif response[:api_error_response] 32 | ErrorResult.new(@gateway, response[:api_error_response]) 33 | else 34 | raise "expected :merchant or :api_error_response" 35 | end 36 | end 37 | end 38 | end 39 | -------------------------------------------------------------------------------- /lib/braintree/modification.rb: -------------------------------------------------------------------------------- 1 | module Braintree 2 | class Modification 3 | include BaseModule 4 | 5 | attr_reader :amount 6 | attr_reader :created_at 7 | attr_reader :current_billing_cycle 8 | attr_reader :description 9 | attr_reader :id 10 | attr_reader :kind 11 | attr_reader :merchant_id 12 | attr_reader :name 13 | attr_reader :never_expires 14 | attr_reader :number_of_billing_cycles 15 | attr_reader :quantity 16 | attr_reader :updated_at 17 | 18 | class << self 19 | protected :new 20 | def _new(*args) 21 | self.new(*args) 22 | end 23 | end 24 | 25 | def initialize(attributes) 26 | set_instance_variables_from_hash(attributes) 27 | @amount = Util.to_big_decimal(amount) 28 | end 29 | 30 | def never_expires? 31 | @never_expires 32 | end 33 | end 34 | end 35 | -------------------------------------------------------------------------------- /lib/braintree/oauth_credentials.rb: -------------------------------------------------------------------------------- 1 | module Braintree 2 | class OAuthCredentials 3 | include BaseModule 4 | 5 | attr_reader :access_token 6 | attr_reader :expires_at 7 | attr_reader :refresh_token 8 | attr_reader :token_type 9 | 10 | def initialize(attributes) 11 | set_instance_variables_from_hash(attributes) 12 | end 13 | 14 | class << self 15 | protected :new 16 | end 17 | 18 | def self._new(*args) 19 | self.new(*args) 20 | end 21 | end 22 | end 23 | -------------------------------------------------------------------------------- /lib/braintree/paginated_collection.rb: -------------------------------------------------------------------------------- 1 | module Braintree 2 | class PaginatedCollection 3 | include Enumerable 4 | 5 | def initialize(&block) 6 | @next_page_block = block 7 | end 8 | 9 | def each(&block) 10 | current_page = 0 11 | total_items = 0 12 | 13 | loop do 14 | current_page += 1 15 | 16 | result = @next_page_block.call(current_page) 17 | total_items = result.total_items 18 | 19 | result.current_page.each(&block) 20 | 21 | break if current_page * result.page_size >= total_items 22 | end 23 | end 24 | end 25 | end 26 | -------------------------------------------------------------------------------- /lib/braintree/paginated_result.rb: -------------------------------------------------------------------------------- 1 | module Braintree 2 | class PaginatedResult 3 | include BaseModule 4 | 5 | attr_reader :current_page 6 | attr_reader :page_size 7 | attr_reader :total_items 8 | 9 | def initialize(total_items, page_size, current_page) 10 | @total_items = total_items 11 | @current_page = current_page 12 | @page_size = page_size 13 | end 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /lib/braintree/payment_instrument_type.rb: -------------------------------------------------------------------------------- 1 | module Braintree 2 | module PaymentInstrumentType 3 | ApplePayCard = "apple_pay_card" 4 | CreditCard = "credit_card" 5 | GooglePayCard = "android_pay_card" 6 | LocalPayment = "local_payment" 7 | MetaCheckoutCard = "meta_checkout_card" 8 | MetaCheckoutToken = "meta_checkout_token" 9 | PayPalAccount = "paypal_account" 10 | PayPalHere = "paypal_here" 11 | # NEXT_MAJOR_VERSION remove SamsungPayCard 12 | SamsungPayCard = "samsung_pay_card" 13 | SepaDirectDebitAccount = "sepa_debit_account" 14 | UsBankAccount = "us_bank_account" 15 | VenmoAccount = "venmo_account" 16 | VisaCheckoutCard = "visa_checkout_card" 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /lib/braintree/payment_method.rb: -------------------------------------------------------------------------------- 1 | module Braintree 2 | class PaymentMethod 3 | include BaseModule 4 | 5 | def self.create(*args) 6 | Configuration.gateway.payment_method.create(*args) 7 | end 8 | 9 | def self.create!(*args) 10 | Configuration.gateway.payment_method.create!(*args) 11 | end 12 | 13 | def self.find(*args) 14 | Configuration.gateway.payment_method.find(*args) 15 | end 16 | 17 | def self.update(*args) 18 | Configuration.gateway.payment_method.update(*args) 19 | end 20 | 21 | def self.update!(*args) 22 | Configuration.gateway.payment_method.update!(*args) 23 | end 24 | 25 | def self.delete(*args) 26 | Configuration.gateway.payment_method.delete(*args) 27 | end 28 | 29 | def self.grant(*args) 30 | Configuration.gateway.payment_method.grant(*args) 31 | end 32 | 33 | def self.revoke(*args) 34 | Configuration.gateway.payment_method.revoke(*args) 35 | end 36 | end 37 | end 38 | -------------------------------------------------------------------------------- /lib/braintree/payment_method_customer_data_updated_metadata.rb: -------------------------------------------------------------------------------- 1 | module Braintree 2 | class PaymentMethodCustomerDataUpdatedMetadata 3 | include BaseModule 4 | 5 | attr_reader :token 6 | attr_reader :payment_method 7 | attr_reader :datetime_updated 8 | attr_reader :enriched_customer_data 9 | 10 | def initialize(gateway, attributes) 11 | set_instance_variables_from_hash(attributes) 12 | @payment_method = PaymentMethodParser.parse_payment_method(gateway, attributes[:payment_method]) 13 | @enriched_customer_data = EnrichedCustomerData._new(enriched_customer_data) if enriched_customer_data 14 | end 15 | 16 | class << self 17 | protected :new 18 | end 19 | 20 | def self._new(*args) 21 | self.new(*args) 22 | end 23 | end 24 | end 25 | -------------------------------------------------------------------------------- /lib/braintree/payment_method_nonce.rb: -------------------------------------------------------------------------------- 1 | module Braintree 2 | class PaymentMethodNonce 3 | include BaseModule 4 | 5 | def self.create(*args) 6 | Configuration.gateway.payment_method_nonce.create(*args) 7 | end 8 | 9 | def self.create!(*args) 10 | Configuration.gateway.payment_method_nonce.create!(*args) 11 | end 12 | 13 | def self.find(*args) 14 | Configuration.gateway.payment_method_nonce.find(*args) 15 | end 16 | 17 | attr_reader :bin_data 18 | attr_reader :default 19 | attr_reader :details 20 | attr_reader :nonce 21 | attr_reader :three_d_secure_info 22 | attr_reader :type 23 | attr_reader :authentication_insight 24 | 25 | def initialize(gateway, attributes) 26 | @gateway = gateway 27 | set_instance_variables_from_hash(attributes) 28 | @details = PaymentMethodNonceDetails.new(attributes[:details]) if attributes[:details] 29 | @three_d_secure_info = ThreeDSecureInfo.new(attributes[:three_d_secure_info]) if attributes[:three_d_secure_info] 30 | @bin_data = BinData.new(attributes[:bin_data]) if attributes[:bin_data] 31 | end 32 | 33 | def default? 34 | @default 35 | end 36 | 37 | def to_s 38 | nonce 39 | end 40 | 41 | class << self 42 | protected :new 43 | end 44 | 45 | def self._new(gateway, attributes) 46 | new(gateway, attributes) 47 | end 48 | end 49 | end 50 | -------------------------------------------------------------------------------- /lib/braintree/payment_method_nonce_details.rb: -------------------------------------------------------------------------------- 1 | module Braintree 2 | class PaymentMethodNonceDetails 3 | include BaseModule 4 | 5 | attr_reader :bin 6 | attr_reader :card_type 7 | attr_reader :expiration_month 8 | attr_reader :expiration_year 9 | attr_reader :is_network_tokenized 10 | attr_reader :last_two 11 | attr_reader :payer_info 12 | attr_reader :sepa_direct_debit_account_nonce_details 13 | 14 | alias_method :is_network_tokenized?, :is_network_tokenized 15 | 16 | def initialize(attributes) 17 | set_instance_variables_from_hash attributes unless attributes.nil? 18 | @payer_info = PaymentMethodNonceDetailsPayerInfo.new(attributes[:payer_info]) if attributes[:payer_info] 19 | @sepa_direct_debit_account_nonce_details = ::Braintree::SepaDirectDebitAccountNonceDetails.new(attributes) 20 | end 21 | 22 | def inspect 23 | attr_order = [ 24 | :bin, 25 | :card_type, 26 | :expiration_month, 27 | :expiration_year, 28 | :is_network_tokenized, 29 | :last_two, 30 | :payer_info, 31 | :sepa_direct_debit_account_nonce_details, 32 | ] 33 | 34 | formatted_attrs = attr_order.map do |attr| 35 | "#{attr}: #{send(attr).inspect}" 36 | end 37 | "#" 38 | end 39 | end 40 | end 41 | -------------------------------------------------------------------------------- /lib/braintree/payment_method_nonce_details_payer_info.rb: -------------------------------------------------------------------------------- 1 | module Braintree 2 | class PaymentMethodNonceDetailsPayerInfo 3 | include BaseModule 4 | 5 | attr_reader :billing_agreement_id 6 | attr_reader :country_code 7 | attr_reader :email 8 | attr_reader :first_name 9 | attr_reader :last_name 10 | attr_reader :payer_id 11 | 12 | def initialize(attributes) 13 | set_instance_variables_from_hash attributes unless attributes.nil? 14 | end 15 | 16 | def inspect 17 | attr_order = [ 18 | :billing_agreement_id, 19 | :country_code, 20 | :email, 21 | :first_name, 22 | :last_name, 23 | :payer_id, 24 | ] 25 | 26 | formatted_attrs = attr_order.map do |attr| 27 | "#{attr}: #{send(attr).inspect}" 28 | end 29 | "#" 30 | end 31 | end 32 | end 33 | -------------------------------------------------------------------------------- /lib/braintree/payment_method_nonce_gateway.rb: -------------------------------------------------------------------------------- 1 | module Braintree 2 | class PaymentMethodNonceGateway 3 | include BaseModule 4 | 5 | def initialize(gateway) 6 | @gateway = gateway 7 | @config = gateway.config 8 | @config.assert_has_access_token_or_keys 9 | end 10 | 11 | def create(payment_method_token, args = {payment_method_nonce: {}}) 12 | Util.verify_keys(PaymentMethodNonceGateway._create_signature, args) 13 | 14 | response = @config.http.post("#{@config.base_merchant_path}/payment_methods/#{payment_method_token}/nonces", args) 15 | payment_method_nonce = PaymentMethodNonce._new(@gateway, response.fetch(:payment_method_nonce)) 16 | SuccessfulResult.new(:payment_method_nonce => payment_method_nonce) 17 | end 18 | 19 | def self._create_signature 20 | [ { 21 | :payment_method_nonce=> [ 22 | :merchant_account_id, :authentication_insight, 23 | {:authentication_insight_options => [:amount, :recurring_customer_consent, :recurring_max_amount]} 24 | ] 25 | }] 26 | end 27 | 28 | def create!(*args) 29 | return_object_or_raise(:payment_method_nonce) { create(*args) } 30 | end 31 | 32 | def find(payment_method_nonce) 33 | response = @config.http.get("#{@config.base_merchant_path}/payment_method_nonces/#{payment_method_nonce}") 34 | payment_method_nonce = PaymentMethodNonce._new(@gateway, response.fetch(:payment_method_nonce)) 35 | SuccessfulResult.new(:payment_method_nonce => payment_method_nonce) 36 | end 37 | end 38 | end 39 | -------------------------------------------------------------------------------- /lib/braintree/payment_method_parser.rb: -------------------------------------------------------------------------------- 1 | module Braintree 2 | module PaymentMethodParser 3 | 4 | def self.parse_payment_method(gateway, attributes) 5 | if attributes[:credit_card] 6 | CreditCard._new(gateway, attributes[:credit_card]) 7 | elsif attributes[:paypal_account] 8 | PayPalAccount._new(gateway, attributes[:paypal_account]) 9 | elsif attributes[:us_bank_account] 10 | UsBankAccount._new(gateway, attributes[:us_bank_account]) 11 | elsif attributes[:apple_pay_card] 12 | ApplePayCard._new(gateway, attributes[:apple_pay_card]) 13 | elsif attributes[:android_pay_card] 14 | GooglePayCard._new(gateway, attributes[:android_pay_card]) 15 | elsif attributes[:venmo_account] 16 | VenmoAccount._new(gateway, attributes[:venmo_account]) 17 | elsif attributes[:visa_checkout_card] 18 | VisaCheckoutCard._new(gateway, attributes[:visa_checkout_card]) 19 | elsif attributes[:samsung_pay_card] 20 | warn "[DEPRECATED] SamsungPayCard is no longer a supported payment method type" 21 | SamsungPayCard._new(gateway, attributes[:samsung_pay_card]) 22 | elsif attributes[:sepa_debit_account] 23 | SepaDirectDebitAccount._new(gateway, attributes[:sepa_debit_account]) 24 | else 25 | UnknownPaymentMethod._new(gateway, attributes) 26 | end 27 | end 28 | end 29 | end 30 | -------------------------------------------------------------------------------- /lib/braintree/paypal_account.rb: -------------------------------------------------------------------------------- 1 | module Braintree 2 | class PayPalAccount 3 | include BaseModule 4 | 5 | attr_reader :billing_agreement_id 6 | attr_reader :created_at 7 | attr_reader :customer_id 8 | attr_reader :edit_paypal_vault_id 9 | attr_reader :email 10 | attr_reader :funding_source_description 11 | attr_reader :image_url 12 | attr_reader :payer_id 13 | attr_reader :revoked_at 14 | attr_reader :subscriptions 15 | attr_reader :token 16 | attr_reader :updated_at 17 | 18 | def initialize(gateway, attributes) 19 | @gateway = gateway 20 | set_instance_variables_from_hash(attributes) 21 | @subscriptions = (@subscriptions || []).map { |subscription_hash| Subscription._new(@gateway, subscription_hash) } 22 | end 23 | 24 | class << self 25 | protected :new 26 | end 27 | 28 | def self._new(*args) 29 | self.new(*args) 30 | end 31 | 32 | def self.create(attributes) 33 | Configuration.gateway.paypal_account.create(attributes) 34 | end 35 | 36 | def self.find(token) 37 | Configuration.gateway.paypal_account.find(token) 38 | end 39 | 40 | def self.update(token, attributes) 41 | Configuration.gateway.paypal_account.update(token, attributes) 42 | end 43 | 44 | def self.delete(token) 45 | Configuration.gateway.paypal_account.delete(token) 46 | end 47 | 48 | def self.sale(token, transaction_attributes) 49 | Configuration.gateway.transaction.sale(transaction_attributes.merge(:payment_method_token => token)) 50 | end 51 | 52 | def self.sale!(token, transaction_attributes) 53 | return_object_or_raise(:transaction) { sale(token, transaction_attributes) } 54 | end 55 | 56 | def default? 57 | @default 58 | end 59 | end 60 | end 61 | -------------------------------------------------------------------------------- /lib/braintree/paypal_payment_resource.rb: -------------------------------------------------------------------------------- 1 | module Braintree 2 | class PayPalPaymentResource 3 | include BaseModule 4 | 5 | def self.update(*args) 6 | Configuration.gateway.paypal_payment_resource.update(*args) 7 | end 8 | 9 | class << self 10 | protected :new 11 | def _new(*args) 12 | self.new(*args) 13 | end 14 | end 15 | 16 | def initialize(gateway, attributes) 17 | @gateway = gateway 18 | set_instance_variables_from_hash(attributes) 19 | end 20 | end 21 | end 22 | 23 | -------------------------------------------------------------------------------- /lib/braintree/plan.rb: -------------------------------------------------------------------------------- 1 | module Braintree 2 | class Plan 3 | include BaseModule 4 | 5 | attr_reader :add_ons 6 | attr_reader :billing_day_of_month 7 | attr_reader :billing_frequency 8 | attr_reader :created_at 9 | attr_reader :currency_iso_code 10 | attr_reader :description 11 | attr_reader :discounts 12 | attr_reader :id 13 | attr_reader :merchant_id 14 | attr_reader :name 15 | attr_reader :number_of_billing_cycles 16 | attr_reader :price 17 | attr_reader :trial_duration 18 | attr_reader :trial_duration_unit 19 | attr_reader :trial_period 20 | attr_reader :updated_at 21 | 22 | def self.all 23 | Configuration.gateway.plan.all 24 | end 25 | 26 | def initialize(gateway, attributes) 27 | @gateway = gateway 28 | set_instance_variables_from_hash(attributes) 29 | add_ons.map! { |attrs| AddOn._new(attrs) } 30 | discounts.map! { |attrs| Discount._new(attrs) } 31 | @price = Util.to_big_decimal(price) 32 | end 33 | 34 | class << self 35 | protected :new 36 | 37 | def create(*args) 38 | Configuration.gateway.plan.create(*args) 39 | end 40 | 41 | def create!(*args) 42 | Configuration.gateway.plan.create!(*args) 43 | end 44 | 45 | def find(*args) 46 | Configuration.gateway.plan.find(*args) 47 | end 48 | 49 | def update(*args) 50 | Configuration.gateway.plan.update(*args) 51 | end 52 | 53 | def update!(*args) 54 | Configuration.gateway.plan.update!(*args) 55 | end 56 | end 57 | 58 | def self._new(*args) 59 | self.new(*args) 60 | end 61 | end 62 | end 63 | -------------------------------------------------------------------------------- /lib/braintree/processor_response_types.rb: -------------------------------------------------------------------------------- 1 | module Braintree 2 | module ProcessorResponseTypes 3 | Approved = "approved" 4 | SoftDeclined = "soft_declined" 5 | HardDeclined = "hard_declined" 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /lib/braintree/resource_collection.rb: -------------------------------------------------------------------------------- 1 | module Braintree 2 | class ResourceCollection 3 | include Enumerable 4 | 5 | attr_reader :ids 6 | 7 | def initialize(response, &block) 8 | @ids = Util.extract_attribute_as_array(response[:search_results], :ids) 9 | @page_size = response[:search_results][:page_size] 10 | @paging_block = block 11 | end 12 | 13 | # Yields each item 14 | def each(&block) 15 | @ids.each_slice(@page_size) do |page_of_ids| 16 | resources = @paging_block.call(page_of_ids) 17 | resources.each(&block) 18 | end 19 | end 20 | 21 | def empty? 22 | @ids.empty? 23 | end 24 | 25 | # Returns the first or the first N items in the collection or nil if the collection is empty 26 | def first(amount = 1) 27 | return nil if @ids.empty? 28 | return @paging_block.call([@ids.first]).first if amount == 1 29 | 30 | @ids.first(amount).each_slice(@page_size).flat_map do |page_of_ids| 31 | @paging_block.call(page_of_ids) 32 | end 33 | end 34 | 35 | # Only the maximum size of a resource collection can be determined since the data on the server can change while 36 | # fetching blocks of results for iteration. For example, customers can be deleted while iterating, so the number 37 | # of results iterated over may be less than the maximum_size. In general, this method should be avoided. 38 | def maximum_size 39 | @ids.size 40 | end 41 | end 42 | end 43 | -------------------------------------------------------------------------------- /lib/braintree/revoked_payment_method_metadata.rb: -------------------------------------------------------------------------------- 1 | module Braintree 2 | class RevokedPaymentMethodMetadata 3 | include BaseModule 4 | 5 | attr_reader :customer_id 6 | attr_reader :token 7 | attr_reader :revoked_payment_method 8 | 9 | def initialize(gateway, attributes) 10 | @revoked_payment_method = PaymentMethodParser.parse_payment_method(gateway, attributes) 11 | @customer_id = @revoked_payment_method.customer_id 12 | @token = @revoked_payment_method.token 13 | end 14 | 15 | class << self 16 | protected :new 17 | def _new(*args) 18 | self.new(*args) 19 | end 20 | end 21 | end 22 | end 23 | -------------------------------------------------------------------------------- /lib/braintree/risk_data.rb: -------------------------------------------------------------------------------- 1 | module Braintree 2 | class RiskData 3 | include BaseModule 4 | 5 | attr_reader :customer_device_id 6 | attr_reader :customer_location_zip 7 | attr_reader :customer_tenure 8 | attr_reader :decision 9 | attr_reader :decision_reasons 10 | attr_reader :device_data_captured 11 | attr_reader :fraud_service_provider 12 | attr_reader :id 13 | attr_reader :liability_shift 14 | attr_reader :transaction_risk_score 15 | 16 | def initialize(attributes) 17 | set_instance_variables_from_hash attributes unless attributes.nil? 18 | @liability_shift = LiabilityShift.new(attributes[:liability_shift]) if attributes[:liability_shift] 19 | end 20 | 21 | def inspect 22 | attr_order = [:id, :decision, :decision_reasons, :device_data_captured, :fraud_service_provider, :liability_shift, :transaction_risk_score] 23 | formatted_attrs = attr_order.map do |attr| 24 | "#{attr}: #{send(attr).inspect}" 25 | end 26 | "#" 27 | end 28 | end 29 | end 30 | -------------------------------------------------------------------------------- /lib/braintree/risk_data/liability_shift.rb: -------------------------------------------------------------------------------- 1 | module Braintree 2 | class RiskData 3 | class LiabilityShift 4 | include BaseModule 5 | 6 | attr_reader :responsible_party 7 | attr_reader :conditions 8 | 9 | def initialize(attributes) 10 | set_instance_variables_from_hash attributes unless attributes.nil? 11 | end 12 | 13 | def inspect 14 | attr_order = [:responsible_party, :conditions] 15 | formatted_attrs = attr_order.map do |attr| 16 | "#{attr}: #{send(attr).inspect}" 17 | end 18 | "#" 19 | end 20 | end 21 | end 22 | end 23 | -------------------------------------------------------------------------------- /lib/braintree/sepa_direct_debit_account.rb: -------------------------------------------------------------------------------- 1 | module Braintree 2 | class SepaDirectDebitAccount 3 | include BaseModule 4 | 5 | attr_reader :bank_reference_token 6 | attr_reader :created_at 7 | attr_reader :customer_id 8 | attr_reader :customer_global_id 9 | attr_reader :default 10 | attr_reader :global_id 11 | attr_reader :image_url 12 | attr_reader :last_4 13 | attr_reader :mandate_type 14 | attr_reader :merchant_or_partner_customer_id 15 | attr_reader :subscriptions 16 | attr_reader :token 17 | attr_reader :updated_at 18 | attr_reader :view_mandate_url 19 | 20 | def initialize(gateway, attributes) 21 | @gateway = gateway 22 | @subscriptions = (@subscriptions || []).map { |subscription_hash| Subscription._new(@gateway, subscription_hash) } 23 | set_instance_variables_from_hash(attributes) 24 | end 25 | 26 | def default? 27 | @default 28 | end 29 | 30 | class << self 31 | protected :new 32 | end 33 | 34 | def self._new(*args) 35 | self.new(*args) 36 | end 37 | 38 | def self.find(*args) 39 | Configuration.gateway.sepa_direct_debit_account.find(*args) 40 | end 41 | 42 | def self.delete(*args) 43 | Configuration.gateway.sepa_direct_debit_account.delete(*args) 44 | end 45 | 46 | def self.sale(token, transaction_attributes) 47 | options = transaction_attributes[:options] || {} 48 | Configuration.gateway.transaction.sale( 49 | transaction_attributes.merge( 50 | :payment_method_token => token, 51 | :options => options.merge(:submit_for_settlement => true), 52 | ), 53 | ) 54 | end 55 | 56 | def self.sale!(token, transaction_attributes) 57 | return_object_or_raise(:transaction) { sale(token, transaction_attributes) } 58 | end 59 | end 60 | end 61 | -------------------------------------------------------------------------------- /lib/braintree/sepa_direct_debit_account_gateway.rb: -------------------------------------------------------------------------------- 1 | module Braintree 2 | class SepaDirectDebitAccountGateway 3 | def initialize(gateway) 4 | @gateway = gateway 5 | @config = gateway.config 6 | @config.assert_has_access_token_or_keys 7 | end 8 | 9 | def find(token) 10 | raise ArgumentError if token.nil? || token.to_s.strip == "" 11 | response = @config.http.get("#{@config.base_merchant_path}/payment_methods/sepa_debit_account/#{token}") 12 | SepaDirectDebitAccount._new(@gateway, response[:sepa_debit_account]) 13 | rescue NotFoundError 14 | raise NotFoundError, "sepa direct debit account with token #{token.inspect} not found" 15 | end 16 | 17 | def delete(token) 18 | raise ArgumentError if token.nil? || token.to_s.strip == "" 19 | @config.http.delete("#{@config.base_merchant_path}/payment_methods/sepa_debit_account/#{token}") 20 | SuccessfulResult.new 21 | rescue NotFoundError 22 | raise NotFoundError, "sepa direct debit account with token #{token.inspect} not found" 23 | end 24 | end 25 | end 26 | -------------------------------------------------------------------------------- /lib/braintree/sepa_direct_debit_account_nonce_details.rb: -------------------------------------------------------------------------------- 1 | module Braintree 2 | class SepaDirectDebitAccountNonceDetails 3 | include BaseModule 4 | 5 | attr_reader :bank_reference_token 6 | attr_reader :last_4 7 | attr_reader :mandate_type 8 | attr_reader :merchant_or_partner_customer_id 9 | 10 | def initialize(attributes) 11 | set_instance_variables_from_hash attributes unless attributes.nil? 12 | end 13 | 14 | def inspect 15 | attr_order = [ 16 | :bank_reference_token, 17 | :last_4, 18 | :mandate_type, 19 | :merchant_or_partner_customer_id, 20 | ] 21 | 22 | formatted_attrs = attr_order.map do |attr| 23 | "#{attr}: #{send(attr).inspect}" 24 | end 25 | "#" 26 | end 27 | end 28 | end 29 | -------------------------------------------------------------------------------- /lib/braintree/settlement_batch_summary.rb: -------------------------------------------------------------------------------- 1 | module Braintree 2 | class SettlementBatchSummary 3 | include BaseModule 4 | 5 | attr_reader :records 6 | 7 | def self.generate(settlement_date, group_by_custom_field = nil) 8 | criteria = {:settlement_date => settlement_date} 9 | criteria.merge!({:group_by_custom_field => group_by_custom_field}) if group_by_custom_field 10 | Configuration.gateway.settlement_batch_summary.generate(criteria) 11 | end 12 | 13 | def initialize(gateway, attributes) 14 | @gateway = gateway 15 | set_instance_variables_from_hash(attributes) 16 | end 17 | 18 | class << self 19 | protected :new 20 | def _new(*args) 21 | self.new(*args) 22 | end 23 | end 24 | end 25 | end 26 | -------------------------------------------------------------------------------- /lib/braintree/settlement_batch_summary_gateway.rb: -------------------------------------------------------------------------------- 1 | module Braintree 2 | class SettlementBatchSummaryGateway 3 | include BaseModule 4 | 5 | def initialize(gateway) 6 | @gateway = gateway 7 | @config = gateway.config 8 | @config.assert_has_access_token_or_keys 9 | end 10 | 11 | def generate(criteria) 12 | Util.verify_keys(_signature, criteria) 13 | response = @config.http.post("#{@config.base_merchant_path}/settlement_batch_summary", :settlement_batch_summary => criteria) 14 | if response[:settlement_batch_summary] 15 | SuccessfulResult.new(:settlement_batch_summary => SettlementBatchSummary._new(@gateway, response[:settlement_batch_summary])) 16 | elsif response[:api_error_response] 17 | ErrorResult.new(@gateway, response[:api_error_response]) 18 | else 19 | raise UnexpectedError, "expected :settlement_batch_summary or :api_error_response" 20 | end 21 | end 22 | 23 | def _signature 24 | [:settlement_date, :group_by_custom_field] 25 | end 26 | end 27 | end 28 | -------------------------------------------------------------------------------- /lib/braintree/sha256_digest.rb: -------------------------------------------------------------------------------- 1 | module Braintree 2 | module SHA256Digest 3 | def self.hexdigest(private_key, string) 4 | _hmac(private_key, string) 5 | end 6 | 7 | def self._hmac(key, message) 8 | key_digest = ::Digest::SHA256.digest(key) 9 | sha256 = OpenSSL::Digest.new("sha256") 10 | OpenSSL::HMAC.hexdigest(sha256, key_digest, message.to_s) 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /lib/braintree/signature_service.rb: -------------------------------------------------------------------------------- 1 | module Braintree 2 | class SignatureService 3 | attr_reader :key 4 | 5 | def initialize(key, digest=Braintree::Digest) 6 | @key = key 7 | @digest = digest 8 | end 9 | 10 | def sign(data) 11 | query_string = Util.hash_to_query_string(data) 12 | "#{hash(query_string)}|#{query_string}" 13 | end 14 | 15 | def hash(data) 16 | @digest.hexdigest(@key, data) 17 | end 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /lib/braintree/subscription/status_details.rb: -------------------------------------------------------------------------------- 1 | module Braintree 2 | class Subscription 3 | class StatusDetails 4 | include BaseModule 5 | 6 | attr_reader :balance 7 | attr_reader :price 8 | attr_reader :status 9 | attr_reader :subscription_source 10 | attr_reader :timestamp 11 | attr_reader :user 12 | attr_reader :currency_iso_code 13 | attr_reader :plan_id 14 | 15 | def initialize(attributes) 16 | set_instance_variables_from_hash attributes unless attributes.nil? 17 | end 18 | end 19 | end 20 | end 21 | -------------------------------------------------------------------------------- /lib/braintree/subscription_search.rb: -------------------------------------------------------------------------------- 1 | module Braintree 2 | class SubscriptionSearch < AdvancedSearch 3 | multiple_value_field :in_trial_period 4 | multiple_value_field :ids 5 | text_fields :id, :transaction_id 6 | multiple_value_or_text_field :plan_id 7 | multiple_value_field :status, :allows => Subscription::Status::All 8 | multiple_value_field :merchant_account_id 9 | range_fields :created_at, :price, :days_past_due, :billing_cycles_remaining, :next_billing_date 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /lib/braintree/successful_result.rb: -------------------------------------------------------------------------------- 1 | module Braintree 2 | class SuccessfulResult 3 | include BaseModule 4 | 5 | attr_reader :address 6 | attr_reader :apple_pay_options 7 | attr_reader :credentials 8 | attr_reader :credit_card 9 | attr_reader :credit_card_verification 10 | attr_reader :customer 11 | attr_reader :disputes 12 | attr_reader :document_upload 13 | attr_reader :evidence 14 | attr_reader :exchange_rate_quote_payload 15 | attr_reader :merchant 16 | attr_reader :merchant_account 17 | attr_reader :merchant_accounts 18 | attr_reader :payment_method 19 | attr_reader :payment_method_nonce 20 | attr_reader :paypal_account 21 | attr_reader :plan 22 | attr_reader :settlement_batch_summary 23 | attr_reader :subscription 24 | attr_reader :supported_networks 25 | attr_reader :transaction 26 | attr_reader :us_bank_account_verification 27 | attr_reader :session_id 28 | attr_reader :customer_recommendations 29 | 30 | def initialize(attributes = {}) 31 | @attrs = attributes.keys 32 | attributes.each do |key, value| 33 | instance_variable_set("@#{key}", value) 34 | end 35 | @credit_card_verification = @verification 36 | end 37 | 38 | def inspect 39 | inspected_attributes = @attrs.map { |attr| "#{attr}:#{send(attr).inspect}" } 40 | "#<#{self.class} #{inspected_attributes.join(" ")}>" 41 | end 42 | 43 | def success? 44 | true 45 | end 46 | end 47 | end 48 | -------------------------------------------------------------------------------- /lib/braintree/test/authentication_id.rb: -------------------------------------------------------------------------------- 1 | module Braintree 2 | module Test 3 | module AuthenticationId 4 | ThreeDSecureVisaFullAuthentication = "fake-three-d-secure-visa-full-authentication-id" 5 | ThreeDSecureVisaLookupTimeout = "fake-three-d-secure-visa-lookup-timeout-id" 6 | ThreeDSecureVisaFailedSignature = "fake-three-d-secure-visa-failed-signature-id" 7 | ThreeDSecureVisaFailedAuthentication = "fake-three-d-secure-visa-failed-authentication-id" 8 | ThreeDSecureVisaAttemptsNonParticipating = "fake-three-d-secure-visa-attempts-non-participating-id" 9 | ThreeDSecureVisaNoteEnrolled = "fake-three-d-secure-visa-not-enrolled-id" 10 | ThreeDSecureVisaUnavailable = "fake-three-d-secure-visa-unavailable-id" 11 | ThreeDSecureVisaMPILookupError = "fake-three-d-secure-visa-mpi-lookup-error-id" 12 | ThreeDSecureVisaMPIAuthenticateError = "fake-three-d-secure-visa-mpi-authenticate-error-id" 13 | ThreeDSecureVisaAuthenticationUnavailable = "fake-three-d-secure-visa-authentication-unavailable-id" 14 | ThreeDSecureVisaBypassedAuthentication = "fake-three-d-secure-visa-bypassed-authentication-id" 15 | ThreeDSecureTwoVisaSuccessfulFrictionlessAuthentication = "fake-three-d-secure-two-visa-successful-frictionless-authentication-id" 16 | ThreeDSecureTwoVisaSuccessfulStepUpAuthentication = "fake-three-d-secure-two-visa-successful-step-up-authentication-id" 17 | ThreeDSecureTwoVisaErrorOnLookup = "fake-three-d-secure-two-visa-error-on-lookup-id" 18 | ThreeDSecureTwoVisaTimeoutOnLookup = "fake-three-d-secure-two-visa-timeout-on-lookup-id" 19 | end 20 | end 21 | end 22 | -------------------------------------------------------------------------------- /lib/braintree/test/merchant_account.rb: -------------------------------------------------------------------------------- 1 | module Braintree 2 | module Test 3 | module MerchantAccount 4 | Approve = "approve_me" 5 | 6 | InsufficientFundsContactUs = "insufficient_funds__contact" 7 | AccountNotAuthorizedContactUs = "account_not_authorized__contact" 8 | BankRejectedUpdateFundingInformation = "bank_rejected__update" 9 | BankRejectedNone = "bank_rejected__none" 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /lib/braintree/test/transaction_amounts.rb: -------------------------------------------------------------------------------- 1 | module Braintree 2 | module Test 3 | # NEXT_MAJOR_VERSION are these even being used anymore? Can we remove this class?? 4 | module TransactionAmounts 5 | Authorize = "1000.00" 6 | Decline = "2000.00" 7 | HardDecline = "2015.00" 8 | Fail = "3000.00" 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /lib/braintree/test/venmo_sdk.rb: -------------------------------------------------------------------------------- 1 | # NEXT_MAJOR_VERSION Remove this class 2 | # The old venmo SDK class has been deprecated 3 | module Braintree 4 | module Test 5 | module VenmoSDK 6 | def self.generate_test_payment_method_code(card_number) 7 | "stub-#{card_number}" 8 | end 9 | 10 | AmExPaymentMethodCode = generate_test_payment_method_code(CreditCardNumbers::AmExes.first) 11 | DiscoverPaymentMethodCode = generate_test_payment_method_code(CreditCardNumbers::Discovers.first) 12 | JCBPaymentMethodCode = generate_test_payment_method_code(CreditCardNumbers::JCBs.first) 13 | MasterCardPaymentMethodCode = generate_test_payment_method_code(CreditCardNumbers::MasterCards.first) 14 | VisaPaymentMethodCode = generate_test_payment_method_code(CreditCardNumbers::Visas.first) 15 | InvalidPaymentMethodCode = "stub-invalid-payment-method-code" 16 | 17 | Session = "stub-session" 18 | InvalidSession = "stub-invalid-session" 19 | end 20 | end 21 | end 22 | -------------------------------------------------------------------------------- /lib/braintree/test_transaction.rb: -------------------------------------------------------------------------------- 1 | module Braintree 2 | class TestTransaction < Transaction 3 | def self.settle(transaction_id) 4 | Configuration.gateway.testing.settle(transaction_id) 5 | end 6 | 7 | def self.settlement_confirm(transaction_id) 8 | Configuration.gateway.testing.settlement_confirm(transaction_id) 9 | end 10 | 11 | def self.settlement_decline(transaction_id) 12 | Configuration.gateway.testing.settlement_decline(transaction_id) 13 | end 14 | 15 | def self.settlement_pending(transaction_id) 16 | Configuration.gateway.testing.settlement_pending(transaction_id) 17 | end 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /lib/braintree/testing_gateway.rb: -------------------------------------------------------------------------------- 1 | module Braintree 2 | class TestingGateway 3 | 4 | def initialize(gateway) 5 | @gateway = gateway 6 | @config = gateway.config 7 | @config.assert_has_access_token_or_keys 8 | @transaction_gateway = TransactionGateway.new(gateway) 9 | end 10 | 11 | def settle(transaction_id) 12 | check_environment 13 | 14 | response = @config.http.put("#{@config.base_merchant_path}/transactions/#{transaction_id}/settle") 15 | @transaction_gateway._handle_transaction_response(response) 16 | end 17 | 18 | def settlement_confirm(transaction_id) 19 | check_environment 20 | 21 | response = @config.http.put("#{@config.base_merchant_path}/transactions/#{transaction_id}/settlement_confirm") 22 | @transaction_gateway._handle_transaction_response(response) 23 | end 24 | 25 | def settlement_decline(transaction_id) 26 | check_environment 27 | 28 | response = @config.http.put("#{@config.base_merchant_path}/transactions/#{transaction_id}/settlement_decline") 29 | @transaction_gateway._handle_transaction_response(response) 30 | end 31 | 32 | def settlement_pending(transaction_id) 33 | check_environment 34 | 35 | response = @config.http.put("#{@config.base_merchant_path}/transactions/#{transaction_id}/settlement_pending") 36 | @transaction_gateway._handle_transaction_response(response) 37 | end 38 | 39 | def check_environment 40 | raise TestOperationPerformedInProduction if @config.environment == :production 41 | end 42 | end 43 | end 44 | -------------------------------------------------------------------------------- /lib/braintree/three_d_secure_info.rb: -------------------------------------------------------------------------------- 1 | module Braintree 2 | class ThreeDSecureInfo 3 | include BaseModule 4 | 5 | attr_reader :acs_transaction_id 6 | attr_reader :cavv 7 | attr_reader :ds_transaction_id 8 | attr_reader :eci_flag 9 | attr_reader :enrolled 10 | attr_reader :liability_shift_possible 11 | attr_reader :liability_shifted 12 | attr_reader :pares_status 13 | attr_reader :status 14 | attr_reader :three_d_secure_authentication_id 15 | attr_reader :three_d_secure_transaction_id 16 | attr_reader :three_d_secure_version 17 | attr_reader :xid 18 | attr_reader :lookup 19 | attr_reader :authentication 20 | 21 | alias_method :liability_shifted?, :liability_shifted 22 | alias_method :liability_shift_possible?, :liability_shift_possible 23 | 24 | def initialize(attributes) 25 | set_instance_variables_from_hash attributes unless attributes.nil? 26 | end 27 | 28 | def inspect 29 | attr_order = [ 30 | :acs_transaction_id, 31 | :authentication, 32 | :cavv, 33 | :ds_transaction_id, 34 | :eci_flag, 35 | :enrolled, 36 | :liability_shift_possible, 37 | :liability_shifted, 38 | :lookup, 39 | :pares_status, 40 | :status, 41 | :three_d_secure_authentication_id, 42 | :three_d_secure_transaction_id, 43 | :three_d_secure_version, 44 | :xid 45 | ] 46 | 47 | formatted_attrs = attr_order.map do |attr| 48 | "#{attr}: #{send(attr).inspect}" 49 | end 50 | "#" 51 | end 52 | end 53 | end 54 | -------------------------------------------------------------------------------- /lib/braintree/transaction/address_details.rb: -------------------------------------------------------------------------------- 1 | module Braintree 2 | class Transaction 3 | class AddressDetails 4 | include BaseModule 5 | 6 | module ShippingMethod 7 | SameDay = "same_day" 8 | NextDay = "next_day" 9 | Priority = "priority" 10 | Ground = "ground" 11 | Electronic = "electronic" 12 | ShipToStore = "ship_to_store" 13 | PickupInStore = "pickup_in_store" 14 | end 15 | 16 | attr_reader :company 17 | attr_reader :country_code_alpha2 18 | attr_reader :country_code_alpha3 19 | attr_reader :country_code_numeric 20 | attr_reader :country_name 21 | attr_reader :extended_address 22 | attr_reader :first_name 23 | attr_reader :id 24 | attr_reader :international_phone 25 | attr_reader :last_name 26 | attr_reader :locality 27 | attr_reader :phone_number 28 | attr_reader :postal_code 29 | attr_reader :region 30 | attr_reader :shipping_method 31 | attr_reader :street_address 32 | 33 | def initialize(attributes) 34 | set_instance_variables_from_hash attributes unless attributes.nil? 35 | end 36 | end 37 | end 38 | end 39 | -------------------------------------------------------------------------------- /lib/braintree/transaction/apple_pay_details.rb: -------------------------------------------------------------------------------- 1 | module Braintree 2 | class Transaction 3 | class ApplePayDetails 4 | include BaseModule 5 | 6 | attr_reader :bin 7 | attr_reader :business 8 | attr_reader :card_type 9 | attr_reader :cardholder_name 10 | attr_reader :commercial 11 | attr_reader :consumer 12 | attr_reader :corporate 13 | attr_reader :country_of_issuance 14 | attr_reader :debit 15 | attr_reader :durbin_regulated 16 | attr_reader :expiration_month 17 | attr_reader :expiration_year 18 | attr_reader :global_id 19 | attr_reader :healthcare 20 | attr_reader :image_url 21 | attr_reader :issuing_bank 22 | attr_reader :last_4 23 | attr_reader :merchant_token_identifier 24 | attr_reader :payment_instrument_name 25 | attr_reader :payroll 26 | attr_reader :prepaid 27 | attr_reader :prepaid_reloadable 28 | attr_reader :product_id 29 | attr_reader :purchase 30 | attr_reader :source_card_last4 31 | attr_reader :source_description 32 | attr_reader :token 33 | 34 | def initialize(attributes) 35 | set_instance_variables_from_hash attributes unless attributes.nil? 36 | end 37 | end 38 | end 39 | end 40 | -------------------------------------------------------------------------------- /lib/braintree/transaction/customer_details.rb: -------------------------------------------------------------------------------- 1 | module Braintree 2 | class Transaction 3 | class CustomerDetails 4 | include BaseModule 5 | 6 | attr_reader :company 7 | attr_reader :email 8 | attr_reader :fax 9 | attr_reader :first_name 10 | attr_reader :id 11 | attr_reader :international_phone 12 | attr_reader :last_name 13 | attr_reader :phone 14 | attr_reader :website 15 | 16 | def initialize(attributes) 17 | set_instance_variables_from_hash attributes unless attributes.nil? 18 | end 19 | 20 | def inspect 21 | attr_order = [:id, :first_name, :last_name, :email, :company, :website, :phone, :international_phone, :fax] 22 | formatted_attrs = attr_order.map do |attr| 23 | "#{attr}: #{send(attr).inspect}" 24 | end 25 | "#<#{formatted_attrs.join(", ")}>" 26 | end 27 | end 28 | end 29 | end 30 | -------------------------------------------------------------------------------- /lib/braintree/transaction/disbursement_details.rb: -------------------------------------------------------------------------------- 1 | module Braintree 2 | class Transaction 3 | class DisbursementDetails 4 | include BaseModule 5 | 6 | attr_reader :disbursement_date 7 | attr_reader :settlement_amount 8 | attr_reader :settlement_currency_exchange_rate 9 | attr_reader :settlement_currency_iso_code 10 | attr_reader :success 11 | 12 | alias_method :success?, :success 13 | 14 | def initialize(attributes) 15 | set_instance_variables_from_hash attributes unless attributes.nil? 16 | @disbursement_date = Date.parse(disbursement_date) unless disbursement_date.nil? 17 | end 18 | 19 | def funds_held? 20 | @funds_held 21 | end 22 | 23 | def valid? 24 | !disbursement_date.nil? 25 | end 26 | end 27 | end 28 | end 29 | -------------------------------------------------------------------------------- /lib/braintree/transaction/google_pay_details.rb: -------------------------------------------------------------------------------- 1 | module Braintree 2 | class Transaction 3 | class GooglePayDetails 4 | include BaseModule 5 | 6 | attr_reader :bin 7 | attr_reader :business 8 | attr_reader :card_type 9 | attr_reader :commercial 10 | attr_reader :consumer 11 | attr_reader :corporate 12 | attr_reader :country_of_issuance 13 | attr_reader :debit 14 | attr_reader :durbin_regulated 15 | attr_reader :expiration_month 16 | attr_reader :expiration_year 17 | attr_reader :global_id 18 | attr_reader :google_transaction_id 19 | attr_reader :healthcare 20 | attr_reader :image_url 21 | attr_reader :issuing_bank 22 | attr_reader :last_4 23 | attr_reader :payroll 24 | attr_reader :prepaid 25 | attr_reader :prepaid_reloadable 26 | attr_reader :product_id 27 | attr_reader :purchase 28 | attr_reader :source_card_last_4 29 | attr_reader :source_card_type 30 | attr_reader :source_description 31 | attr_reader :token 32 | attr_reader :virtual_card_last_4 33 | attr_reader :virtual_card_type 34 | 35 | def initialize(attributes) 36 | set_instance_variables_from_hash attributes unless attributes.nil? 37 | @card_type = @virtual_card_type 38 | @last_4 = @virtual_card_last_4 39 | end 40 | 41 | def is_network_tokenized? 42 | @is_network_tokenized 43 | end 44 | end 45 | end 46 | end 47 | -------------------------------------------------------------------------------- /lib/braintree/transaction/installment.rb: -------------------------------------------------------------------------------- 1 | module Braintree 2 | class Transaction 3 | class Installment 4 | include BaseModule 5 | 6 | attr_reader :id 7 | attr_reader :amount 8 | attr_reader :projected_disbursement_date 9 | attr_reader :actual_disbursement_date 10 | attr_reader :adjustments 11 | 12 | def initialize(attributes) 13 | set_instance_variables_from_hash attributes unless attributes.nil? 14 | @amount = Util.to_big_decimal(amount) 15 | adjustments.map! { |attrs| Adjustment.new(attrs) } if adjustments 16 | end 17 | 18 | def inspect 19 | attrs = [:id, :amount, :projected_disbursement_date, :actual_disbursement_date, :adjustments] 20 | formatted_attrs = attrs.map do |attr| 21 | "#{attr}: #{send(attr).inspect}" 22 | end 23 | 24 | "#<#{formatted_attrs.join(", ")}>" 25 | end 26 | end 27 | end 28 | end 29 | -------------------------------------------------------------------------------- /lib/braintree/transaction/installment/adjustment.rb: -------------------------------------------------------------------------------- 1 | module Braintree 2 | class Transaction 3 | class Installment 4 | class Adjustment 5 | include BaseModule 6 | 7 | module Kind 8 | Refund = "REFUND" 9 | Dispute = "DISPUTE" 10 | end 11 | 12 | attr_reader :amount 13 | attr_reader :kind 14 | attr_reader :projected_disbursement_date 15 | attr_reader :actual_disbursement_date 16 | 17 | def initialize(attributes) 18 | set_instance_variables_from_hash attributes unless attributes.nil? 19 | @amount = Util.to_big_decimal(amount) 20 | end 21 | 22 | def inspect 23 | attrs = [:amount, :kind, :projected_disbursement_date, :actual_disbursement_date] 24 | formatted_attrs = attrs.map do |attr| 25 | "#{attr}: #{send(attr).inspect}" 26 | end 27 | 28 | "#<#{formatted_attrs.join(", ")}>" 29 | end 30 | end 31 | end 32 | end 33 | end 34 | -------------------------------------------------------------------------------- /lib/braintree/transaction/local_payment_details.rb: -------------------------------------------------------------------------------- 1 | module Braintree 2 | class Transaction 3 | class LocalPaymentDetails 4 | include BaseModule 5 | 6 | attr_reader :blik_aliases 7 | attr_reader :capture_id 8 | attr_reader :custom_field 9 | attr_reader :debug_id 10 | attr_reader :description 11 | attr_reader :funding_source 12 | attr_reader :implicitly_vaulted_payment_method_global_id 13 | attr_reader :implicitly_vaulted_payment_method_token 14 | attr_reader :payer_id 15 | attr_reader :payment_id 16 | attr_reader :refund_from_transaction_fee_amount 17 | attr_reader :refund_from_transaction_fee_currency_iso_code 18 | attr_reader :refund_id 19 | attr_reader :transaction_fee_amount 20 | attr_reader :transaction_fee_currency_iso_code 21 | 22 | def initialize(attributes) 23 | set_instance_variables_from_hash attributes unless attributes.nil? 24 | end 25 | end 26 | end 27 | end 28 | -------------------------------------------------------------------------------- /lib/braintree/transaction/package_details.rb: -------------------------------------------------------------------------------- 1 | module Braintree 2 | class Transaction 3 | class PackageDetails 4 | include BaseModule 5 | 6 | attr_reader :carrier 7 | attr_reader :id 8 | # NEXT_MAJOR_VERSION Remove this method 9 | # use paypal_tracker_id going forward 10 | attr_reader :paypal_tracking_id 11 | attr_reader :paypal_tracker_id 12 | attr_reader :tracking_number 13 | 14 | def initialize(attributes) 15 | set_instance_variables_from_hash attributes unless attributes.nil? 16 | end 17 | end 18 | end 19 | end -------------------------------------------------------------------------------- /lib/braintree/transaction/payment_receipt.rb: -------------------------------------------------------------------------------- 1 | module Braintree 2 | class Transaction 3 | class PaymentReceipt 4 | include BaseModule 5 | 6 | attr_reader :account_balance 7 | attr_reader :amount 8 | attr_reader :card_last_4 9 | attr_reader :card_present_data 10 | attr_reader :card_type 11 | attr_reader :currency_iso_code 12 | attr_reader :global_id 13 | attr_reader :id 14 | attr_reader :merchant_address 15 | attr_reader :merchant_identification_number 16 | attr_reader :merchant_name 17 | attr_reader :pin_verified 18 | attr_reader :processor_authorization_code 19 | attr_reader :processor_response_code 20 | attr_reader :processor_response_text 21 | attr_reader :terminal_identification_number 22 | attr_reader :type 23 | 24 | def initialize(attributes) 25 | set_instance_variables_from_hash attributes unless attributes.nil? 26 | @card_present_data = CardPresentData.new(attributes[:card_present_date]) if attributes[:card_present_data] 27 | @merchant_address = MerchantAddress.new(attributes[:merchant_address]) if attributes[:merchant_address] 28 | end 29 | end 30 | end 31 | end 32 | -------------------------------------------------------------------------------- /lib/braintree/transaction/payment_receipt/card_present_data.rb: -------------------------------------------------------------------------------- 1 | module Braintree 2 | class Transaction 3 | class PaymentReceipt 4 | class CardPresentData 5 | include BaseModule 6 | 7 | attr_reader :application_cryptogram 8 | attr_reader :application_identifier 9 | attr_reader :application_interchange_profile 10 | attr_reader :application_name 11 | attr_reader :application_transaction_counter 12 | attr_reader :application_usage_control 13 | attr_reader :authorization_mode 14 | attr_reader :authorization_response_code 15 | attr_reader :card_entry_method 16 | attr_reader :card_sequence_number 17 | attr_reader :cardholder_verification_method_results 18 | attr_reader :cashback_amount 19 | attr_reader :cryptogram_information_data 20 | attr_reader :issuer_action_code_default 21 | attr_reader :issuer_action_code_denial 22 | attr_reader :issuer_action_code_online 23 | attr_reader :issuer_authentication_data 24 | attr_reader :terminal_country_code 25 | attr_reader :terminal_transaction_date 26 | attr_reader :terminal_transaction_type 27 | attr_reader :terminal_verification_result 28 | attr_reader :unpredictable_number 29 | 30 | def initialize(attributes) 31 | set_instance_variables_from_hash attributes unless attributes.nil? 32 | end 33 | end 34 | end 35 | end 36 | end 37 | -------------------------------------------------------------------------------- /lib/braintree/transaction/payment_receipt/merchant_address.rb: -------------------------------------------------------------------------------- 1 | module Braintree 2 | class Transaction 3 | class PaymentReceipt 4 | class MerchantAddress 5 | include BaseModule 6 | 7 | attr_reader :locality 8 | attr_reader :phone 9 | attr_reader :postal_code 10 | attr_reader :region 11 | attr_reader :street_address 12 | 13 | def initialize(attributes) 14 | set_instance_variables_from_hash attributes unless attributes.nil? 15 | end 16 | end 17 | end 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /lib/braintree/transaction/paypal_details.rb: -------------------------------------------------------------------------------- 1 | module Braintree 2 | class Transaction 3 | class PayPalDetails 4 | include BaseModule 5 | 6 | attr_reader :authorization_id 7 | attr_reader :billing_agreement_id 8 | attr_reader :capture_id 9 | attr_reader :custom_field 10 | attr_reader :debug_id 11 | attr_reader :description 12 | attr_reader :image_url 13 | attr_reader :implicitly_vaulted_payment_method_global_id 14 | attr_reader :implicitly_vaulted_payment_method_token 15 | attr_reader :payee_email 16 | attr_reader :payee_id 17 | attr_reader :payer_email 18 | attr_reader :payer_first_name 19 | attr_reader :payer_id 20 | attr_reader :payer_last_name 21 | attr_reader :payer_status 22 | attr_reader :payment_id 23 | attr_reader :recipient_email 24 | attr_reader :recipient_phone 25 | attr_reader :refund_from_transaction_fee_amount 26 | attr_reader :refund_from_transaction_fee_currency_iso_code 27 | attr_reader :refund_id 28 | attr_reader :seller_protection_status 29 | attr_reader :tax_id 30 | attr_reader :tax_id_type 31 | attr_reader :token 32 | attr_reader :transaction_fee_amount 33 | attr_reader :transaction_fee_currency_iso_code 34 | 35 | def initialize(attributes) 36 | set_instance_variables_from_hash attributes unless attributes.nil? 37 | end 38 | end 39 | end 40 | end 41 | -------------------------------------------------------------------------------- /lib/braintree/transaction/paypal_here_details.rb: -------------------------------------------------------------------------------- 1 | module Braintree 2 | class Transaction 3 | class PayPalHereDetails 4 | include BaseModule 5 | 6 | attr_reader :authorization_id 7 | attr_reader :capture_id 8 | attr_reader :invoice_id 9 | attr_reader :last_4 10 | attr_reader :payment_id 11 | attr_reader :payment_type 12 | attr_reader :refund_id 13 | attr_reader :transaction_fee_amount 14 | attr_reader :transaction_fee_currency_iso_code 15 | attr_reader :transaction_initiation_date 16 | attr_reader :transaction_updated_date 17 | 18 | def initialize(attributes) 19 | set_instance_variables_from_hash attributes unless attributes.nil? 20 | end 21 | end 22 | end 23 | end 24 | -------------------------------------------------------------------------------- /lib/braintree/transaction/samsung_pay_card_details.rb: -------------------------------------------------------------------------------- 1 | module Braintree 2 | class Transaction 3 | # NEXT_MAJOR_VERSION remove this class 4 | # SamsungPayCard has been deprecated 5 | class SamsungPayCardDetails 6 | include BaseModule 7 | 8 | attr_reader :bin 9 | attr_reader :cardholder_name 10 | attr_reader :card_type 11 | attr_reader :commercial 12 | attr_reader :country_of_issuance 13 | attr_reader :customer_location 14 | attr_reader :debit 15 | attr_reader :durbin_regulated 16 | attr_reader :expiration_month 17 | attr_reader :expiration_year 18 | attr_reader :healthcare 19 | attr_reader :image_url 20 | attr_reader :issuing_bank 21 | attr_reader :last_4 22 | attr_reader :payroll 23 | attr_reader :prepaid 24 | attr_reader :product_id 25 | attr_reader :source_card_last_4 26 | attr_reader :token 27 | 28 | def initialize(attributes) 29 | set_instance_variables_from_hash attributes unless attributes.nil? 30 | end 31 | 32 | def expiration_date 33 | "#{expiration_month}/#{expiration_year}" 34 | end 35 | 36 | def inspect 37 | attr_order = [:token, :bin, :last_4, :card_type, :expiration_date, :source_card_last_4, :customer_location, :prepaid, 38 | :healthcare, :durbin_regulated, :debit, :commercial, :payroll, :product_id, :country_of_issuance, :issuing_bank, :image_url] 39 | formatted_attrs = attr_order.map do |attr| 40 | "#{attr}: #{send(attr).inspect}" 41 | end 42 | "#<#{formatted_attrs.join(", ")}>" 43 | end 44 | 45 | def masked_number 46 | "#{bin}******#{last_4}" 47 | end 48 | end 49 | end 50 | end 51 | -------------------------------------------------------------------------------- /lib/braintree/transaction/sepa_direct_debit_account_details.rb: -------------------------------------------------------------------------------- 1 | module Braintree 2 | class Transaction 3 | class SepaDirectDebitAccountDetails 4 | include BaseModule 5 | 6 | attr_reader :bank_reference_token 7 | attr_reader :capture_id 8 | attr_reader :debug_id 9 | attr_reader :global_id 10 | attr_reader :last_4 11 | attr_reader :mandate_type 12 | attr_reader :merchant_or_partner_customer_id 13 | attr_reader :paypal_v2_order_id 14 | attr_reader :refund_from_transaction_fee_amount 15 | attr_reader :refund_from_transaction_fee_currency_iso_code 16 | attr_reader :refund_id 17 | attr_reader :settlement_type 18 | attr_reader :token 19 | attr_reader :transaction_fee_amount 20 | attr_reader :transaction_fee_currency_iso_code 21 | 22 | def initialize(attributes) 23 | set_instance_variables_from_hash attributes unless attributes.nil? 24 | end 25 | end 26 | end 27 | end 28 | -------------------------------------------------------------------------------- /lib/braintree/transaction/status_details.rb: -------------------------------------------------------------------------------- 1 | module Braintree 2 | class Transaction 3 | class StatusDetails 4 | include BaseModule 5 | 6 | attr_reader :amount 7 | attr_reader :status 8 | attr_reader :timestamp 9 | attr_reader :transaction_source 10 | attr_reader :user 11 | 12 | def initialize(attributes) 13 | set_instance_variables_from_hash attributes unless attributes.nil? 14 | end 15 | end 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /lib/braintree/transaction/subscription_details.rb: -------------------------------------------------------------------------------- 1 | module Braintree 2 | class Transaction 3 | class SubscriptionDetails 4 | include BaseModule 5 | 6 | attr_reader :billing_period_end_date 7 | attr_reader :billing_period_start_date 8 | 9 | def initialize(attributes) 10 | set_instance_variables_from_hash attributes unless attributes.nil? 11 | @billing_period_start_date = Date.parse(billing_period_start_date) unless billing_period_start_date.nil? 12 | @billing_period_end_date = Date.parse(billing_period_end_date) unless billing_period_end_date.nil? 13 | end 14 | end 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /lib/braintree/transaction/us_bank_account_details.rb: -------------------------------------------------------------------------------- 1 | module Braintree 2 | class Transaction 3 | class UsBankAccountDetails 4 | include BaseModule 5 | 6 | attr_reader :account_holder_name 7 | attr_reader :account_type 8 | attr_reader :ach_mandate 9 | attr_reader :bank_name 10 | attr_reader :global_id 11 | attr_reader :image_url 12 | attr_reader :last_4 13 | attr_reader :routing_number 14 | attr_reader :token 15 | 16 | def initialize(attributes) 17 | set_instance_variables_from_hash attributes unless attributes.nil? 18 | @ach_mandate = attributes[:ach_mandate] ? AchMandate.new(attributes[:ach_mandate]) : nil 19 | end 20 | end 21 | end 22 | end 23 | -------------------------------------------------------------------------------- /lib/braintree/transaction/venmo_account_details.rb: -------------------------------------------------------------------------------- 1 | module Braintree 2 | class Transaction 3 | class VenmoAccountDetails 4 | include BaseModule 5 | 6 | attr_reader :image_url 7 | attr_reader :source_description 8 | attr_reader :token 9 | attr_reader :username 10 | attr_reader :venmo_user_id 11 | 12 | def initialize(attributes) 13 | set_instance_variables_from_hash attributes unless attributes.nil? 14 | end 15 | end 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /lib/braintree/transaction/visa_checkout_card_details.rb: -------------------------------------------------------------------------------- 1 | module Braintree 2 | class Transaction 3 | class VisaCheckoutCardDetails 4 | include BaseModule 5 | 6 | attr_reader :bin 7 | attr_reader :business 8 | attr_reader :call_id 9 | attr_reader :card_type 10 | attr_reader :cardholder_name 11 | attr_reader :commercial 12 | attr_reader :consumer 13 | attr_reader :corporate 14 | attr_reader :country_of_issuance 15 | attr_reader :customer_location 16 | attr_reader :debit 17 | attr_reader :durbin_regulated 18 | attr_reader :expiration_month 19 | attr_reader :expiration_year 20 | attr_reader :healthcare 21 | attr_reader :image_url 22 | attr_reader :issuing_bank 23 | attr_reader :last_4 24 | attr_reader :payroll 25 | attr_reader :prepaid 26 | attr_reader :prepaid_reloadable 27 | attr_reader :product_id 28 | attr_reader :purchase 29 | attr_reader :token 30 | 31 | def initialize(attributes) 32 | set_instance_variables_from_hash attributes unless attributes.nil? 33 | end 34 | 35 | def expiration_date 36 | "#{expiration_month}/#{expiration_year}" 37 | end 38 | 39 | def inspect 40 | attr_order = [ 41 | :bin, :business, :call_id, :card_type, :cardholder_name, :commercial, :consumer, :corporate, 42 | :country_of_issuance, :customer_location, :debit, :durbin_regulated, :expiration_date, 43 | :healthcare, :image_url, :issuing_bank, :last_4, :payroll, :prepaid, :prepaid_reloadable, 44 | :product_id, :purchase, :token] 45 | formatted_attrs = attr_order.map do |attr| 46 | "#{attr}: #{send(attr).inspect}" 47 | end 48 | "#<#{formatted_attrs.join(", ")}>" 49 | end 50 | 51 | def masked_number 52 | "#{bin}******#{last_4}" 53 | end 54 | end 55 | end 56 | end 57 | -------------------------------------------------------------------------------- /lib/braintree/transaction_line_item.rb: -------------------------------------------------------------------------------- 1 | module Braintree 2 | class TransactionLineItem 3 | include BaseModule 4 | attr_reader :commodity_code 5 | attr_reader :description 6 | attr_reader :discount_amount 7 | attr_reader :image_url 8 | attr_reader :kind 9 | attr_reader :name 10 | attr_reader :product_code 11 | attr_reader :quantity 12 | attr_reader :tax_amount 13 | attr_reader :total_amount 14 | attr_reader :unit_amount 15 | attr_reader :unit_of_measure 16 | attr_reader :unit_tax_amount 17 | attr_reader :upc_code 18 | attr_reader :upc_type 19 | attr_reader :url 20 | 21 | def initialize(gateway, attributes) 22 | @gateway = gateway 23 | set_instance_variables_from_hash(attributes) 24 | @quantity = Util.to_big_decimal(quantity) 25 | @unit_amount = Util.to_big_decimal(unit_amount) 26 | @unit_tax_amount = Util.to_big_decimal(unit_tax_amount) 27 | @discount_amount = Util.to_big_decimal(discount_amount) 28 | @tax_amount = Util.to_big_decimal(tax_amount) 29 | @total_amount = Util.to_big_decimal(total_amount) 30 | end 31 | 32 | class << self 33 | protected :new 34 | def _new(*args) 35 | self.new(*args) 36 | end 37 | end 38 | 39 | def self.find_all(*args) 40 | Configuration.gateway.transaction_line_item.find_all(*args) 41 | end 42 | end 43 | end 44 | -------------------------------------------------------------------------------- /lib/braintree/transaction_line_item_gateway.rb: -------------------------------------------------------------------------------- 1 | module Braintree 2 | class TransactionLineItemGateway 3 | def initialize(gateway) 4 | @gateway = gateway 5 | @config = gateway.config 6 | @config.assert_has_access_token_or_keys 7 | end 8 | 9 | def find_all(transaction_id) 10 | raise ArgumentError, "transaction_id cannot be blank" if transaction_id.nil? || transaction_id.strip.to_s == "" 11 | response = @config.http.get("#{@config.base_merchant_path}/transactions/#{transaction_id}/line_items") 12 | response[:line_items].map do |line_item_params| 13 | TransactionLineItem._new(@gateway, line_item_params) 14 | end 15 | rescue NotFoundError 16 | raise NotFoundError, "transaction with id #{transaction_id.inspect} not found" 17 | end 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /lib/braintree/transaction_review.rb: -------------------------------------------------------------------------------- 1 | module Braintree 2 | class TransactionReview 3 | include BaseModule 4 | 5 | attr_reader :transaction_id, :decision, :reviewer_email, :reviewer_note, :reviewer_time 6 | 7 | def initialize(attributes) 8 | set_instance_variables_from_hash(attributes) 9 | end 10 | 11 | class << self 12 | protected :new 13 | def _new(*args) 14 | self.new(*args) 15 | end 16 | end 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /lib/braintree/unknown_payment_method.rb: -------------------------------------------------------------------------------- 1 | module Braintree 2 | class UnknownPaymentMethod 3 | include BaseModule 4 | 5 | attr_reader :customer_id 6 | attr_reader :token 7 | 8 | def initialize(gateway, attributes) 9 | @gateway = gateway 10 | nested_attributes = attributes[attributes.keys.first] 11 | set_instance_variables_from_hash(nested_attributes) 12 | end 13 | 14 | def default? 15 | @default 16 | end 17 | 18 | def image_url 19 | "https://assets.braintreegateway.com/payment_method_logo/unknown.png" 20 | end 21 | 22 | def self._new(*args) 23 | self.new(*args) 24 | end 25 | end 26 | end 27 | -------------------------------------------------------------------------------- /lib/braintree/us_bank_account.rb: -------------------------------------------------------------------------------- 1 | module Braintree 2 | class UsBankAccount 3 | include BaseModule 4 | 5 | attr_reader :account_holder_name 6 | attr_reader :account_type 7 | attr_reader :ach_mandate 8 | attr_reader :bank_name 9 | attr_reader :default 10 | attr_reader :image_url 11 | attr_reader :last_4 12 | attr_reader :routing_number 13 | attr_reader :token 14 | attr_reader :verifications 15 | attr_reader :verified 16 | 17 | def initialize(gateway, attributes) 18 | @gateway = gateway 19 | set_instance_variables_from_hash(attributes) 20 | @ach_mandate = AchMandate.new(attributes[:ach_mandate]) if attributes[:ach_mandate] 21 | 22 | if attributes[:verifications] 23 | @verifications = attributes[:verifications].map do |v| 24 | UsBankAccountVerification._new(v) 25 | end 26 | end 27 | end 28 | 29 | def default? 30 | @default 31 | end 32 | 33 | class << self 34 | protected :new 35 | end 36 | 37 | def self._new(*args) 38 | self.new(*args) 39 | end 40 | 41 | def self.find(*args) 42 | Configuration.gateway.us_bank_account.find(*args) 43 | end 44 | 45 | def self.sale(token, transaction_attributes) 46 | Configuration.gateway.transaction.sale(transaction_attributes.merge( 47 | :payment_method_token => token, 48 | :options => {:submit_for_settlement => true}, 49 | ), 50 | ) 51 | end 52 | 53 | def self.sale!(token, transaction_attributes) 54 | return_object_or_raise(:transaction) { sale(token, transaction_attributes) } 55 | end 56 | end 57 | end 58 | -------------------------------------------------------------------------------- /lib/braintree/us_bank_account_gateway.rb: -------------------------------------------------------------------------------- 1 | module Braintree 2 | class UsBankAccountGateway 3 | def initialize(gateway) 4 | @gateway = gateway 5 | @config = gateway.config 6 | @config.assert_has_access_token_or_keys 7 | end 8 | 9 | def find(token) 10 | raise ArgumentError if token.nil? || token.to_s.strip == "" 11 | response = @config.http.get("#{@config.base_merchant_path}/payment_methods/us_bank_account/#{token}") 12 | UsBankAccount._new(@gateway, response[:us_bank_account]) 13 | rescue NotFoundError 14 | raise NotFoundError, "payment method with token #{token.inspect} not found" 15 | end 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /lib/braintree/us_bank_account_verification_search.rb: -------------------------------------------------------------------------------- 1 | module Braintree 2 | class UsBankAccountVerificationSearch < AdvancedSearch 3 | text_fields( 4 | :id, 5 | :account_holder_name, 6 | :routing_number, 7 | :payment_method_token, 8 | :customer_id, 9 | :customer_email, 10 | ) 11 | 12 | multiple_value_field :verification_method, :allows => UsBankAccountVerification::VerificationMethod::All 13 | multiple_value_field :status, :allows => UsBankAccountVerification::Status::All 14 | multiple_value_field :ids 15 | ends_with_fields :account_number 16 | range_fields :created_at 17 | equality_fields :account_type 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /lib/braintree/validation_error.rb: -------------------------------------------------------------------------------- 1 | module Braintree 2 | class ValidationError 3 | include BaseModule 4 | 5 | attr_reader :attribute 6 | attr_reader :code 7 | attr_reader :message 8 | 9 | def initialize(error_hash) 10 | # parse GraphQL response objects 11 | if (error_hash[:extensions] && 12 | error_hash[:extensions][:errorClass] && 13 | error_hash[:extensions][:errorClass] == "VALIDATION") 14 | error_hash[:code] = error_hash[:extensions][:legacyCode].to_i 15 | error_hash[:attribute] = error_hash[:path].last 16 | end 17 | 18 | set_instance_variables_from_hash error_hash 19 | end 20 | 21 | def inspect 22 | "#<#{self.class} (#{code}) #{message}>" 23 | end 24 | end 25 | end 26 | -------------------------------------------------------------------------------- /lib/braintree/venmo_account.rb: -------------------------------------------------------------------------------- 1 | module Braintree 2 | class VenmoAccount 3 | include BaseModule 4 | 5 | attr_reader :created_at 6 | attr_reader :customer_id 7 | attr_reader :default 8 | attr_reader :image_url 9 | attr_reader :source_description 10 | attr_reader :subscriptions 11 | attr_reader :token 12 | attr_reader :updated_at 13 | attr_reader :username 14 | attr_reader :venmo_user_id 15 | 16 | def initialize(gateway, attributes) 17 | @gateway = gateway 18 | set_instance_variables_from_hash(attributes) 19 | @subscriptions = (@subscriptions || []).map { |subscription_hash| Subscription._new(@gateway, subscription_hash) } 20 | end 21 | 22 | def default? 23 | @default 24 | end 25 | 26 | class << self 27 | protected :new 28 | end 29 | 30 | def self._new(*args) 31 | self.new(*args) 32 | end 33 | end 34 | end 35 | -------------------------------------------------------------------------------- /lib/braintree/venmo_profile_data.rb: -------------------------------------------------------------------------------- 1 | module Braintree 2 | class VenmoProfileData 3 | include BaseModule 4 | 5 | attr_reader :billing_address 6 | attr_reader :email 7 | attr_reader :first_name 8 | attr_reader :last_name 9 | attr_reader :phone_number 10 | attr_reader :shipping_address 11 | attr_reader :username 12 | 13 | def initialize(attributes) 14 | set_instance_variables_from_hash(attributes) 15 | end 16 | 17 | class << self 18 | protected :new 19 | end 20 | 21 | def self._new(*args) 22 | self.new(*args) 23 | end 24 | end 25 | end 26 | -------------------------------------------------------------------------------- /lib/braintree/version.rb: -------------------------------------------------------------------------------- 1 | module Braintree 2 | module Version 3 | Major = 4 4 | Minor = 28 5 | Tiny = 0 6 | 7 | String = "#{Major}.#{Minor}.#{Tiny}" 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /lib/braintree/webhook_testing.rb: -------------------------------------------------------------------------------- 1 | module Braintree 2 | class WebhookTesting 3 | def self.sample_notification(*args) 4 | Configuration.gateway.webhook_testing.sample_notification(*args) 5 | end 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /lib/braintree/xml.rb: -------------------------------------------------------------------------------- 1 | module Braintree 2 | module Xml 3 | def self.hash_from_xml(xml) 4 | Parser.hash_from_xml(xml) 5 | end 6 | 7 | def self.hash_to_xml(hash) 8 | Generator.hash_to_xml(hash) 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /polaris.yml: -------------------------------------------------------------------------------- 1 | # This is the default configuration file generated by Polaris. Documentation on configuration options can be found here https://sig-docs.synopsys.com/polaris/topics/c_conf-overview.html 2 | version: "1" 3 | project: 4 | name: ${scm.git.repo} 5 | branch: ${scm.git.branch} 6 | revision: 7 | name: ${scm.git.commit} 8 | date: ${scm.git.commit.date} 9 | groups: 10 | # Required: This allows the Jenkins Polaris service account to create new projects 11 | braintree-jenkins: "Contributor" 12 | PP_SSO_POLARIS_USER: "Observer" 13 | PP_SSO_POLARIS_SECURITY_CHAMPION: "Contributor" 14 | PP_SSO_POLARIS_ADMIN: "Administrator" 15 | capture: 16 | fileSystem: 17 | ears: 18 | extensions: [ear] 19 | files: 20 | - directory: ${project.projectDir} 21 | java: 22 | files: 23 | - directory: ${project.projectDir} 24 | javascript: 25 | files: 26 | - directory: ${project.projectDir} 27 | - excludeRegex: node_modules|bower_components|vendor 28 | php: 29 | files: 30 | - directory: ${project.projectDir} 31 | python: 32 | files: 33 | - directory: ${project.projectDir} 34 | ruby: 35 | files: 36 | - directory: ${project.projectDir} 37 | typescript: 38 | files: 39 | - directory: ${project.projectDir} 40 | wars: 41 | extensions: [war] 42 | files: 43 | - directory: ${project.projectDir} 44 | analyze: 45 | mode: central 46 | install: 47 | coverity: 48 | version: default 49 | serverUrl: ${POLARIS_SERVER_URL} -------------------------------------------------------------------------------- /spec/.gitignore: -------------------------------------------------------------------------------- 1 | httpsd.pid 2 | -------------------------------------------------------------------------------- /spec/fixtures/files/bt_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/braintree/braintree_ruby/931c7c454ac09bbedfb68b5c6160ffaa4843feac/spec/fixtures/files/bt_logo.png -------------------------------------------------------------------------------- /spec/fixtures/files/gif_extension_bt_logo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/braintree/braintree_ruby/931c7c454ac09bbedfb68b5c6160ffaa4843feac/spec/fixtures/files/gif_extension_bt_logo.gif -------------------------------------------------------------------------------- /spec/fixtures/files/malformed_pdf.pdf: -------------------------------------------------------------------------------- 1 | XXXXXXXXXXX¾?^gfkbfu¶šÙú”¼Åxc¯ÄÖñ•:x„BºS·É=] óqçÅÒÐwî+= x wÁ¼/7ú7ÀݛeÀÅA¿8?À­‹6Á2[î(†¤Ö@+3[ß} 2 | -------------------------------------------------------------------------------- /spec/fixtures/files/too_long.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/braintree/braintree_ruby/931c7c454ac09bbedfb68b5c6160ffaa4843feac/spec/fixtures/files/too_long.pdf -------------------------------------------------------------------------------- /spec/integration/braintree/add_on_spec.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path(File.dirname(__FILE__) + "/../spec_helper") 2 | 3 | describe Braintree::AddOn do 4 | describe "self.all" do 5 | it "gets all add_ons" do 6 | id = rand(36**8).to_s(36) 7 | 8 | expected = { 9 | :amount => "100.00", 10 | :description => "some description", 11 | :id => id, 12 | :kind => "add_on", 13 | :name => "ruby_add_on", 14 | :never_expires => false, 15 | :number_of_billing_cycles => 1 16 | } 17 | 18 | create_modification_for_tests(expected) 19 | 20 | add_ons = Braintree::AddOn.all 21 | add_on = add_ons.select { |add_on| add_on.id == id }.first 22 | 23 | expect(add_on).not_to be_nil 24 | expect(add_on.amount).to eq(BigDecimal(expected[:amount])) 25 | expect(add_on.created_at).not_to be_nil 26 | expect(add_on.description).to eq(expected[:description]) 27 | expect(add_on.kind).to eq(expected[:kind]) 28 | expect(add_on.name).to eq(expected[:name]) 29 | expect(add_on.never_expires).to eq(expected[:never_expires]) 30 | expect(add_on.number_of_billing_cycles).to eq(expected[:number_of_billing_cycles]) 31 | expect(add_on.updated_at).not_to be_nil 32 | end 33 | 34 | it "raises with a helpful error if public_key and private_key are not set" do 35 | gateway = Braintree::Gateway.new( 36 | :client_id => "client_id$#{Braintree::Configuration.environment}$integration_client_id", 37 | :client_secret => "client_secret$#{Braintree::Configuration.environment}$integration_client_secret", 38 | :logger => Logger.new("/dev/null"), 39 | ) 40 | 41 | expect do 42 | gateway.add_on.all 43 | end.to raise_error(Braintree::ConfigurationError, /access_token or public_key and private_key are required/) 44 | end 45 | end 46 | end 47 | -------------------------------------------------------------------------------- /spec/integration/braintree/disbursement_spec.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path(File.dirname(__FILE__) + "/../../spec_helper") 2 | 3 | describe Braintree::Disbursement do 4 | describe "transactions" do 5 | it "finds the transactions associated with the disbursement" do 6 | attributes = { 7 | :id => "123456", 8 | :merchant_account => { 9 | :id => "sandbox_sub_merchant_account", 10 | :master_merchant_account => { 11 | :id => "sandbox_master_merchant_account", 12 | :status => "active" 13 | }, 14 | :status => "active" 15 | }, 16 | :transaction_ids => ["sub_merchant_transaction"], 17 | :amount => "100.00", 18 | :disbursement_date => "2013-04-10", 19 | :exception_message => "invalid_account_number", 20 | :follow_up_action => "update", 21 | :retry => false, 22 | :success => false 23 | } 24 | 25 | disbursement = Braintree::Disbursement._new(Braintree::Configuration.gateway, attributes) 26 | expect(disbursement.transactions.maximum_size).to eq(1) 27 | transaction = disbursement.transactions.first 28 | expect(transaction.id).to eq("sub_merchant_transaction") 29 | end 30 | end 31 | end -------------------------------------------------------------------------------- /spec/integration/braintree/discount_spec.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path(File.dirname(__FILE__) + "/../spec_helper") 2 | 3 | describe Braintree::Discount do 4 | describe "self.all" do 5 | it "gets all discounts" do 6 | id = rand(36**8).to_s(36) 7 | 8 | expected = { 9 | :amount => "100.00", 10 | :description => "some description", 11 | :id => id, 12 | :kind => "discount", 13 | :name => "ruby_discount", 14 | :never_expires => false, 15 | :number_of_billing_cycles => 1 16 | } 17 | 18 | create_modification_for_tests(expected) 19 | 20 | discounts = Braintree::Discount.all 21 | discount = discounts.select { |discount| discount.id == id }.first 22 | 23 | expect(discount).not_to be_nil 24 | expect(discount.amount).to eq(BigDecimal(expected[:amount])) 25 | expect(discount.created_at).not_to be_nil 26 | expect(discount.description).to eq(expected[:description]) 27 | expect(discount.kind).to eq(expected[:kind]) 28 | expect(discount.name).to eq(expected[:name]) 29 | expect(discount.never_expires).to eq(expected[:never_expires]) 30 | expect(discount.number_of_billing_cycles).to eq(expected[:number_of_billing_cycles]) 31 | expect(discount.updated_at).not_to be_nil 32 | end 33 | end 34 | end 35 | -------------------------------------------------------------------------------- /spec/integration/braintree/error_codes_spec.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path(File.dirname(__FILE__) + "/../spec_helper") 2 | 3 | describe Braintree::ErrorCodes do 4 | describe Braintree::ErrorCodes::CreditCard do 5 | it "returns CardholderNameIsTooLong when cardholder name is too long" do 6 | result = Braintree::Customer.create( 7 | :credit_card => { 8 | :cardholder_name => "x" * 256 9 | }, 10 | ) 11 | expect(result.success?).to eq(false) 12 | expect(result.errors.for(:customer).for(:credit_card).map { |e| e.code }).to \ 13 | include(Braintree::ErrorCodes::CreditCard::CardholderNameIsTooLong) 14 | end 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /spec/integration/braintree/test/transaction_amounts_spec.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path(File.dirname(__FILE__) + "/../../spec_helper") 2 | 3 | describe Braintree::Test::TransactionAmounts do 4 | describe "Authorize" do 5 | it "creates a transaction with status authorized" do 6 | transaction = Braintree::Transaction.sale!( 7 | :amount => Braintree::Test::TransactionAmounts::Authorize, 8 | :credit_card => { 9 | :number => Braintree::Test::CreditCardNumbers::Visa, 10 | :expiration_date => "12/2012" 11 | }, 12 | ) 13 | expect(transaction.status).to eq(Braintree::Transaction::Status::Authorized) 14 | end 15 | end 16 | 17 | describe "Decline" do 18 | it "creates a transaction with status processor_declined" do 19 | result = Braintree::Transaction.sale( 20 | :amount => Braintree::Test::TransactionAmounts::Decline, 21 | :credit_card => { 22 | :number => Braintree::Test::CreditCardNumbers::Visa, 23 | :expiration_date => "12/2012" 24 | }, 25 | ) 26 | expect(result.transaction.status).to eq(Braintree::Transaction::Status::ProcessorDeclined) 27 | end 28 | end 29 | end 30 | -------------------------------------------------------------------------------- /spec/integration/braintree/transaction_line_item_spec.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path(File.dirname(__FILE__) + "/../spec_helper") 2 | require File.expand_path(File.dirname(__FILE__) + "/client_api/spec_helper") 3 | 4 | describe Braintree::TransactionLineItem do 5 | describe "self.find_all" do 6 | it "returns line_items for the specified transaction" do 7 | result = Braintree::Transaction.create( 8 | :type => "sale", 9 | :amount => Braintree::Test::TransactionAmounts::Authorize, 10 | :credit_card => { 11 | :number => Braintree::Test::CreditCardNumbers::Visa, 12 | :expiration_date => "05/2009" 13 | }, 14 | :line_items => [ 15 | { 16 | :quantity => "1.0232", 17 | :name => "Name #1", 18 | :kind => "debit", 19 | :unit_amount => "45.1232", 20 | :total_amount => "45.15", 21 | :upc_code => "11223344556677889", 22 | :upc_type => "UPC-A", 23 | :image_url => "https://google.com/image.png", 24 | }, 25 | ], 26 | ) 27 | expect(result.success?).to eq(true) 28 | transaction = result.transaction 29 | 30 | line_items = Braintree::TransactionLineItem.find_all(transaction.id) 31 | 32 | line_item = line_items[0] 33 | expect(line_item.quantity).to eq(BigDecimal("1.0232")) 34 | expect(line_item.name).to eq("Name #1") 35 | expect(line_item.kind).to eq("debit") 36 | expect(line_item.unit_amount).to eq(BigDecimal("45.1232")) 37 | expect(line_item.total_amount).to eq(BigDecimal("45.15")) 38 | expect(line_item.upc_type).to eq("UPC-A") 39 | expect(line_item.upc_code).to eq("11223344556677889") 40 | expect(line_item.image_url).to eq("https://google.com/image.png") 41 | end 42 | end 43 | end 44 | 45 | -------------------------------------------------------------------------------- /spec/oauth_test_helper.rb: -------------------------------------------------------------------------------- 1 | module Braintree 2 | class OAuthTestHelper 3 | def self.create_grant(gateway, params) 4 | response = gateway.config.http.post("/oauth_testing/grants", { 5 | :grant => params 6 | }) 7 | response[:grant][:code] 8 | end 9 | 10 | def self.create_token(gateway, params) 11 | code = create_grant(gateway, params) 12 | gateway.oauth.create_token_from_code( 13 | :code => code, 14 | ) 15 | end 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /spec/script/httpsd.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require "webrick" 3 | require "webrick/https" 4 | require "openssl" 5 | 6 | private_key_file = File.expand_path(File.join(File.dirname(__FILE__), "..", "ssl", "privateKey.key")) 7 | cert_file = File.expand_path(File.join(File.dirname(__FILE__), "..", "ssl", "certificate.crt")) 8 | 9 | pkey = OpenSSL::PKey::RSA.new(File.read(private_key_file)) 10 | cert = OpenSSL::X509::Certificate.new(File.read(cert_file)) 11 | 12 | pid_file = ARGV[0] 13 | 14 | s = WEBrick::HTTPServer.new( 15 | :Port => (ENV["SSL_TEST_PORT"] || 8444), 16 | :Logger => WEBrick::Log::new(nil, WEBrick::Log::ERROR), 17 | :DocumentRoot => File.join(File.dirname(__FILE__)), 18 | :ServerType => WEBrick::Daemon, 19 | :SSLEnable => true, 20 | :SSLVerifyClient => OpenSSL::SSL::VERIFY_NONE, 21 | :SSLCertificate => cert, 22 | :SSLPrivateKey => pkey, 23 | :SSLCertName => [ [ "CN",WEBrick::Utils::getservername ] ], 24 | :StartCallback => proc { File.open(pid_file, "w") { |f| f.write $$.to_s } }, 25 | ) 26 | trap("INT") { s.shutdown } 27 | s.start 28 | -------------------------------------------------------------------------------- /spec/spec.opts: -------------------------------------------------------------------------------- 1 | --format progress 2 | --loadby mtime 3 | --reverse 4 | --backtrace 5 | -------------------------------------------------------------------------------- /spec/ssl/certificate.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIICsDCCAhmgAwIBAgIJALYNz+IiqwdkMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV 3 | BAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBX 4 | aWRnaXRzIFB0eSBMdGQwHhcNMDkxMjAyMjI1NTE3WhcNMTAxMjAyMjI1NTE3WjBF 5 | MQswCQYDVQQGEwJBVTETMBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50 6 | ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB 7 | gQCrUO6cm5QqdJLLcMIygeIzyBUYl7iWiHqPy6fmxzj3SsFbTAY8tXT8C2jh3cWi 8 | 0qNGXuxwSK6pClFwkPmW5znjCPbq9Ifa6mAU4+NoCzjTCAWxY3K1p6eW2s1gA82J 9 | BJF9/X4umdx9NbkOeoZWselJa7K0hztjOSBZXjXNfMYOiQIDAQABo4GnMIGkMB0G 10 | A1UdDgQWBBRhqocfWHXEx0mT/IEFR1I5fqCHAjB1BgNVHSMEbjBsgBRhqocfWHXE 11 | x0mT/IEFR1I5fqCHAqFJpEcwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgTClNvbWUt 12 | U3RhdGUxITAfBgNVBAoTGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZIIJALYNz+Ii 13 | qwdkMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADgYEAqeNLmBTdAGcdiTqS 14 | XfmLqbykyq1Qogg+J6s7uNhnP42tuvmHXrE0tC9cn8stbgYzTF4661f/AS97jOOn 15 | cL7c2kXzTzX+fiAd+dMHOckTBoTzRT95/YlphddJNvcdl2q/e2aWMg2VEnIqShJP 16 | jyWXlHrUWbOazZzroZwY9WviUdo= 17 | -----END CERTIFICATE----- 18 | -------------------------------------------------------------------------------- /spec/ssl/geotrust_global.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIDVDCCAjygAwIBAgIDAjRWMA0GCSqGSIb3DQEBBQUAMEIxCzAJBgNVBAYTAlVT 3 | MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i 4 | YWwgQ0EwHhcNMDIwNTIxMDQwMDAwWhcNMjIwNTIxMDQwMDAwWjBCMQswCQYDVQQG 5 | EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEbMBkGA1UEAxMSR2VvVHJ1c3Qg 6 | R2xvYmFsIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2swYYzD9 7 | 9BcjGlZ+W988bDjkcbd4kdS8odhM+KhDtgPpTSEHCIjaWC9mOSm9BXiLnTjoBbdq 8 | fnGk5sRgprDvgOSJKA+eJdbtg/OtppHHmMlCGDUUna2YRpIuT8rxh0PBFpVXLVDv 9 | iS2Aelet8u5fa9IAjbkU+BQVNdnARqN7csiRv8lVK83Qlz6cJmTM386DGXHKTubU 10 | 1XupGc1V3sjs0l44U+VcT4wt/lAjNvxm5suOpDkZALeVAjmRCw7+OC7RHQWa9k0+ 11 | bw8HHa8sHo9gOeL6NlMTOdReJivbPagUvTLrGAMoUgRx5aszPeE4uwc2hGKceeoW 12 | MPRfwCvocWvk+QIDAQABo1MwUTAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTA 13 | ephojYn7qwVkDBF9qn1luMrMTjAfBgNVHSMEGDAWgBTAephojYn7qwVkDBF9qn1l 14 | uMrMTjANBgkqhkiG9w0BAQUFAAOCAQEANeMpauUvXVSOKVCUn5kaFOSPeCpilKIn 15 | Z57QzxpeR+nBsqTP3UEaBU6bS+5Kb1VSsyShNwrrZHYqLizz/Tt1kL/6cdjHPTfS 16 | tQWVYrmm3ok9Nns4d0iXrKYgjy6myQzCsplFAMfOEVEiIuCl6rYVSAlk6l5PdPcF 17 | PseKUgzbFbS9bZvlxrFUaKnjaZC2mqUPuLk/IH2uSrW4nOQdtqvmlKXBx4Ot2/Un 18 | hw4EbNX/3aBd7YdStysVAq45pmp06drE57xNNB6pXE0zX5IJL4hmXXeXxx12E6nV 19 | 5fEWCRE11azbJHFwLJhWC9kXtNHjUStedejV0NxPNO3CBWaAocvmMw== 20 | -----END CERTIFICATE----- 21 | -------------------------------------------------------------------------------- /spec/ssl/privateKey.key: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | MIICXAIBAAKBgQCrUO6cm5QqdJLLcMIygeIzyBUYl7iWiHqPy6fmxzj3SsFbTAY8 3 | tXT8C2jh3cWi0qNGXuxwSK6pClFwkPmW5znjCPbq9Ifa6mAU4+NoCzjTCAWxY3K1 4 | p6eW2s1gA82JBJF9/X4umdx9NbkOeoZWselJa7K0hztjOSBZXjXNfMYOiQIDAQAB 5 | AoGBAI0I/rdc+XiOKb9kH+u2s8NPZ9asKSF8T/ILhjleL46eM1p21veppxpMRlcT 6 | 3T2zTQmE4f96RpgRT4RtRZyu1R6zaSuVlmnKeD8BwEFgYaJUNBHyJuiG2f59gD5f 7 | S09NOXqvHQVMxUKYm9GZ3IG9TVQkpZlytXg8Y1SIHI9Cz8jRAkEA2CTGVWLuke/Z 8 | T+40+TSAbxOpXt7zyq1CO/jp7NsAy3MLIv3GHgxVzcK8tsAEyvPvRSnmMFdciZCx 9 | 5yTfFMHt1QJBAMroCmhLJWcwpjH5mO4kD/1eZNre1j5ZgGTt9fiIxo8Gns6kDLWX 10 | 7iLZ5sAdqle9KUm4BZKvnBtwFkBAwf9Pk+UCQBbdhRHBXoWXvwCCrZ3zXObjSJad 11 | tWKqg4g+o9iHroTXTcVM3WmOWoFi6X3XwGoL9jL15MEWbNastPVD5EmY3mUCQBj4 12 | Pzegb8ToHrutrJ05wOH8OMsaeyEHIJ7LDeb85fp55Rcm5w192edeC2B/BhRwCeGx 13 | jLYFeF+EBqj3jygdIeUCQGExaHBVu0nTHY9CnvJOjc2hs/I3TPwgXzm8rBisGm5W 14 | g0eJhfZ1uJ+oHaKhoTRgB6OOUVnpugx83vYvYiKj+1M= 15 | -----END RSA PRIVATE KEY----- 16 | -------------------------------------------------------------------------------- /spec/unit/braintree/base_module_spec.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path(File.dirname(__FILE__) + "/../spec_helper") 2 | 3 | describe Braintree::BaseModule do 4 | describe "return_object_or_raise" do 5 | it "inspects the error_result when inspecting the exception" do 6 | result = Braintree::ErrorResult.new(:gateway, :errors => {}) 7 | begin 8 | klass = Class.new { include Braintree::BaseModule } 9 | klass.return_object_or_raise(:obj) { result } 10 | rescue Braintree::ValidationsFailed => ex 11 | expect(ex).not_to eq(nil) 12 | expect(ex.error_result).to eq(result) 13 | expect(ex.inspect).to include(result.inspect) 14 | expect(ex.to_s).to include(result.inspect) 15 | end 16 | end 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /spec/unit/braintree/client_token_spec.rb: -------------------------------------------------------------------------------- 1 | 2 | require File.expand_path(File.dirname(__FILE__) + "/../spec_helper") 3 | 4 | module Braintree 5 | describe ClientToken do 6 | describe "self.generate" do 7 | it "delegates to ClientTokenGateway#generate" do 8 | options = {:foo => :bar} 9 | client_token_gateway = double(:client_token_gateway) 10 | expect(client_token_gateway).to receive(:generate).with(options).once 11 | allow(ClientTokenGateway).to receive(:new).and_return(client_token_gateway) 12 | ClientToken.generate(options) 13 | end 14 | 15 | it "can't overwrite public_key, or created_at" do 16 | expect { 17 | Braintree::ClientToken.generate( 18 | :public_key => "bad_key", 19 | :created_at => "bad_time", 20 | ) 21 | }.to raise_error(ArgumentError, /created_at, public_key/) 22 | end 23 | end 24 | 25 | context "adding credit_card options with no customer ID" do 26 | %w(verify_card fail_on_duplicate_payment_method make_default fail_on_duplicate_payment_method_for_customer).each do |option_name| 27 | it "raises an ArgumentError if #{option_name} is present" do 28 | expect do 29 | Braintree::ClientToken.generate( 30 | option_name.to_sym => true, 31 | ) 32 | end.to raise_error(ArgumentError, /#{option_name}/) 33 | end 34 | end 35 | end 36 | end 37 | end 38 | -------------------------------------------------------------------------------- /spec/unit/braintree/digest_spec.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path(File.dirname(__FILE__) + "/../spec_helper") 2 | 3 | describe Braintree::Digest do 4 | describe "self.hexdigest" do 5 | it "returns the sha1 hmac of the input string (test case 6 from RFC 2202)" do 6 | private_key = "\xaa" * 80 7 | data = "Test Using Larger Than Block-Size Key - Hash Key First" 8 | expect(Braintree::Digest.hexdigest(private_key, data)).to eq("aa4ae5e15272d00e95705637ce8a3b55ed402112") 9 | end 10 | 11 | it "returns the sha1 hmac of the input string (test case 7 from RFC 2202)" do 12 | private_key = "\xaa" * 80 13 | data = "Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data" 14 | expect(Braintree::Digest.hexdigest(private_key, data)).to eq("e8e99d0f45237d786d6bbaa7965c7808bbff1a91") 15 | end 16 | 17 | it "doesn't blow up if message is nil" do 18 | expect { Braintree::Digest.hexdigest("key", nil) }.to_not raise_error 19 | end 20 | end 21 | 22 | describe "self.secure_compare" do 23 | it "returns true if two strings are equal" do 24 | expect(Braintree::Digest.secure_compare("A_string", "A_string")).to be(true) 25 | end 26 | 27 | it "returns false if two strings are different and the same length" do 28 | expect(Braintree::Digest.secure_compare("A_string", "A_strong")).to be(false) 29 | end 30 | 31 | it "returns false if one is a prefix of the other" do 32 | expect(Braintree::Digest.secure_compare("A_string", "A_string_that_is_longer")).to be(false) 33 | end 34 | end 35 | end 36 | 37 | -------------------------------------------------------------------------------- /spec/unit/braintree/document_upload_spec.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path(File.dirname(__FILE__) + "/../spec_helper") 2 | 3 | describe Braintree::DocumentUpload do 4 | describe "initialize" do 5 | it "sets attributes" do 6 | response = {:size => 555, :kind => "evidence_document", :name => "up_file.pdf", :content_type => "application/pdf", :id => "my_id"} 7 | document_upload = Braintree::DocumentUpload._new(response) 8 | expect(document_upload.id).to eq("my_id") 9 | expect(document_upload.size).to eq(555) 10 | expect(document_upload.name).to eq("up_file.pdf") 11 | expect(document_upload.content_type).to eq("application/pdf") 12 | expect(document_upload.kind).to eq(Braintree::DocumentUpload::Kind::EvidenceDocument) 13 | end 14 | end 15 | 16 | describe "kind" do 17 | it "sets identity document" do 18 | response = {:size => 555, :kind => "identity_document", :name => "up_file.pdf", :content_type => "application/pdf", :id => "my_id"} 19 | document_upload = Braintree::DocumentUpload._new(response) 20 | expect(document_upload.kind).to eq(Braintree::DocumentUpload::Kind::IdentityDocument) 21 | end 22 | 23 | it "sets evidence document" do 24 | response = {:size => 555, :kind => "evidence_document", :name => "up_file.pdf", :content_type => "application/pdf", :id => "my_id"} 25 | document_upload = Braintree::DocumentUpload._new(response) 26 | expect(document_upload.kind).to eq(Braintree::DocumentUpload::Kind::EvidenceDocument) 27 | end 28 | 29 | it "sets payout invoice document" do 30 | response = {:size => 555, :kind => "payout_invoice_document", :name => "up_file.pdf", :content_type => "application/pdf", :id => "my_id"} 31 | document_upload = Braintree::DocumentUpload._new(response) 32 | expect(document_upload.kind).to eq(Braintree::DocumentUpload::Kind::PayoutInvoiceDocument) 33 | end 34 | end 35 | end 36 | -------------------------------------------------------------------------------- /spec/unit/braintree/enriched_customer_data_spec.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path(File.dirname(__FILE__) + "/../spec_helper") 2 | 3 | describe Braintree::EnrichedCustomerData do 4 | describe "self.new" do 5 | it "is protected" do 6 | expect do 7 | Braintree::EnrichedCustomerData.new 8 | end.to raise_error(NoMethodError, /protected method .new/) 9 | end 10 | end 11 | 12 | describe "self._new" do 13 | it "initializes the object with the appropriate attributes set" do 14 | 15 | address = { 16 | street_address: "a-street-address", 17 | extended_address: "an-extended-address", 18 | locality: "a-locality", 19 | region: "a-region", 20 | postal_code: "a-postal-code" 21 | } 22 | params = { 23 | fields_updated: ["username"], 24 | profile_data: { 25 | username: "a-username", 26 | first_name: "a-first-name", 27 | last_name: "a-last-name", 28 | phone_number: "a-phone-number", 29 | email: "a-email", 30 | billing_address: address, 31 | shipping_address: address, 32 | }, 33 | } 34 | 35 | payment_method_customer_data_updated = Braintree::EnrichedCustomerData._new(params) 36 | 37 | expect(payment_method_customer_data_updated.profile_data).to be_a(Braintree::VenmoProfileData) 38 | expect(payment_method_customer_data_updated.fields_updated).to eq(["username"]) 39 | end 40 | end 41 | end 42 | -------------------------------------------------------------------------------- /spec/unit/braintree/exchange_rate_quote_input_spec.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path(File.dirname(__FILE__) + "/../spec_helper") 2 | 3 | describe Braintree::ExchangeRateQuoteInput do 4 | let(:exchange_rate_quote_input) do 5 | { 6 | base_currency: "USD", 7 | quote_currency: "EUR", 8 | base_amount: "10.00", 9 | markup: "2.00" 10 | } 11 | end 12 | 13 | describe "#initialize" do 14 | it "initialize and sets the input keys to attrs variable" do 15 | quote_input = described_class.new(exchange_rate_quote_input) 16 | 17 | expect(quote_input.attrs).to include(:base_currency) 18 | expect(quote_input.attrs).to include(:quote_currency) 19 | expect(quote_input.attrs).to include(:base_amount) 20 | expect(quote_input.attrs).to include(:markup) 21 | expect(quote_input.attrs.length).to eq(4) 22 | end 23 | end 24 | 25 | describe "inspect" do 26 | it "includes the base_currency first" do 27 | output = described_class.new(base_currency: "USD").inspect 28 | 29 | expect(output).to include("#") 30 | end 31 | 32 | it "includes all quote input attributes" do 33 | quote_input = described_class.new(exchange_rate_quote_input) 34 | output = quote_input.inspect 35 | 36 | expect(output).to include("base_currency:\"USD\"") 37 | expect(output).to include("quote_currency:\"EUR\"") 38 | expect(output).to include("base_amount:\"10.00\"") 39 | expect(output).to include("markup:\"2.00\"") 40 | end 41 | end 42 | end 43 | -------------------------------------------------------------------------------- /spec/unit/braintree/exchange_rate_quote_response_spec.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path(File.dirname(__FILE__) + "/../spec_helper") 2 | 3 | describe Braintree::ExchangeRateQuoteResponse do 4 | describe "#initialize" do 5 | it "creates and validated the exchange rate quote payload" do 6 | quote_payload = Braintree::ExchangeRateQuoteResponse.new( 7 | quotes: [ 8 | { 9 | :base_amount => "10.00", 10 | :quote_amount => "9.03", 11 | :exchange_rate => "0.90" 12 | }, 13 | { 14 | :base_amount => "20.00", 15 | :quote_amount => "18.06", 16 | :exchange_rate => "0.90" 17 | } 18 | ], 19 | ) 20 | 21 | quote_1 = quote_payload.quotes[0] 22 | quote_2 = quote_payload.quotes[1] 23 | 24 | expect(quote_1.base_amount).to eq("10.00") 25 | expect(quote_1.quote_amount).to eq("9.03") 26 | expect(quote_1.exchange_rate).to eq("0.90") 27 | 28 | expect(quote_2.base_amount).to eq("20.00") 29 | expect(quote_2.quote_amount).to eq("18.06") 30 | expect(quote_1.exchange_rate).to eq("0.90") 31 | end 32 | end 33 | 34 | describe "inspect" do 35 | it "prints the attributes" do 36 | exchange_rate_quote_payload = Braintree::ExchangeRateQuoteResponse.new( 37 | quotes: [ 38 | { 39 | :base_amount => "10.00", 40 | :quote_amount => "9.03" 41 | }, 42 | { 43 | :base_amount => "20.00", 44 | :quote_amount => "18.06" 45 | } 46 | ], 47 | ) 48 | 49 | expect(exchange_rate_quote_payload.inspect).to eq(%(#, #]>)) 50 | end 51 | end 52 | end 53 | -------------------------------------------------------------------------------- /spec/unit/braintree/exchange_rate_quote_spec.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path(File.dirname(__FILE__) + "/../spec_helper") 2 | 3 | describe Braintree::ExchangeRateQuote do 4 | let(:rate_quote) do 5 | { 6 | id: "1234", 7 | base_amount: "10.00", 8 | exchange_rate: "74", 9 | quote_amount: "740" 10 | } 11 | end 12 | 13 | describe "#initialize" do 14 | it "initialize and sets the input keys to attrs variable" do 15 | quote = described_class.new(rate_quote) 16 | 17 | expect(quote.attrs).to include(:id) 18 | expect(quote.attrs).to include(:base_amount) 19 | expect(quote.attrs).to include(:exchange_rate) 20 | expect(quote.attrs).to include(:quote_amount) 21 | expect(quote.attrs.length).to eq(4) 22 | end 23 | end 24 | 25 | describe "inspect" do 26 | it "includes the id first" do 27 | output = described_class.new(id: "1234").inspect 28 | 29 | expect(output).to include("#") 30 | end 31 | 32 | it "includes all quote attributes" do 33 | quote = described_class.new(rate_quote) 34 | output = quote.inspect 35 | 36 | expect(output).to include("id:\"1234\"") 37 | expect(output).to include("base_amount:\"10.00\"") 38 | expect(output).to include("exchange_rate:\"74\"") 39 | expect(output).to include("quote_amount:\"740\"") 40 | end 41 | end 42 | end 43 | -------------------------------------------------------------------------------- /spec/unit/braintree/exchange_rate_spec.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path(File.dirname(__FILE__) + "/../spec_helper") 2 | 3 | describe ::Braintree::ExchangeRate do 4 | let(:rate_quote) do 5 | { 6 | id: "1234", 7 | base_amount: "10.00", 8 | exchange_rate: "74", 9 | quote_amount: "740" 10 | } 11 | end 12 | 13 | describe "#initialize" do 14 | it "initialize and sets the attributes" do 15 | exchange_rate = described_class.new(:gateway, rate_quote).inspect 16 | 17 | expect(exchange_rate).to include("@id=\"1234\"") 18 | expect(exchange_rate).to include("@base_amount=\"10.00\"") 19 | expect(exchange_rate).to include("@exchange_rate=\"74\"") 20 | expect(exchange_rate).to include("@quote_amount=\"740\"") 21 | end 22 | end 23 | end 24 | -------------------------------------------------------------------------------- /spec/unit/braintree/google_pay_card_spec.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path(File.dirname(__FILE__) + "/../spec_helper") 2 | 3 | describe Braintree::GooglePayCard do 4 | it "initializes prepaid reloadable correctly" do 5 | card = Braintree::GooglePayCard._new(:gateway, {:prepaid_reloadable => "No"}) 6 | expect(card.prepaid_reloadable).to eq("No") 7 | end 8 | 9 | it "initializes business correctly" do 10 | card = Braintree::GooglePayCard._new(:gateway, {:business => "No"}) 11 | expect(card.business).to eq("No") 12 | end 13 | 14 | it "initializes consumer correctly" do 15 | card = Braintree::GooglePayCard._new(:gateway, {:consumer => "No"}) 16 | expect(card.consumer).to eq("No") 17 | end 18 | 19 | it "initializes corporate correctly" do 20 | card = Braintree::GooglePayCard._new(:gateway, {:corporate => "No"}) 21 | expect(card.corporate).to eq("No") 22 | end 23 | 24 | it "initializes purchase correctly" do 25 | card = Braintree::GooglePayCard._new(:gateway, {:purchase => "No"}) 26 | expect(card.purchase).to eq("No") 27 | end 28 | end 29 | -------------------------------------------------------------------------------- /spec/unit/braintree/graphql/customer_recommendations_spec.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path(File.dirname(__FILE__) + "/../../spec_helper") 2 | 3 | describe Braintree::CustomerRecommendations do 4 | let(:recommendation_data) do 5 | [ 6 | { 7 | paymentOption: "PAYPAL", 8 | recommendedPriority: 1 9 | }, 10 | { 11 | paymentOption: "VENMO", 12 | recommendedPriority: 2 13 | } 14 | ] 15 | end 16 | 17 | describe "#initialize" do 18 | it "creates payment_recommendations correctly" do 19 | recs = Braintree::CustomerRecommendations.new(payment_recommendations: recommendation_data) 20 | expect(recs.payment_recommendations.size).to eq(2) 21 | expect(recs.payment_recommendations.first).to be_a(Braintree::PaymentRecommendations) 22 | expect(recs.payment_recommendations.first.payment_option).to eq("PAYPAL") 23 | expect(recs.payment_recommendations.last.payment_option).to eq("VENMO") 24 | end 25 | 26 | it "creates payment_options from payment_recommendations" do 27 | recs = Braintree::CustomerRecommendations.new(payment_recommendations: recommendation_data) 28 | expect(recs.payment_options.size).to eq(2) 29 | expect(recs.payment_options.first).to be_a(Braintree::PaymentOptions) 30 | expect(recs.payment_options.first.payment_option).to eq("PAYPAL") 31 | expect(recs.payment_options.last.payment_option).to eq("VENMO") 32 | end 33 | 34 | it "is null safe if no recommendations are passed in" do 35 | recs = Braintree::CustomerRecommendations.new 36 | expect(recs.payment_recommendations).to eq([]) 37 | expect(recs.payment_options).to eq([]) 38 | end 39 | end 40 | end -------------------------------------------------------------------------------- /spec/unit/braintree/graphql/phone_input_spec.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path(File.dirname(__FILE__) + "/../../spec_helper") 2 | 3 | 4 | describe Braintree::PhoneInput do 5 | let(:phone_input_data) do 6 | { 7 | country_phone_code: "1", 8 | phone_number: "555-123-4567", 9 | extension_number: "123" 10 | } 11 | end 12 | 13 | let(:partial_phone_input_data) do 14 | { 15 | country_phone_code: "1", 16 | phone_number: "555-123-4567" 17 | } 18 | end 19 | 20 | 21 | describe "#initialize" do 22 | it "initialize and sets the input keys to attrs variable" do 23 | phone_input = described_class.new(phone_input_data) 24 | 25 | expect(phone_input.attrs).to include(:country_phone_code) 26 | expect(phone_input.attrs).to include(:phone_number) 27 | expect(phone_input.attrs).to include(:extension_number) 28 | expect(phone_input.attrs.length).to eq(3) 29 | end 30 | end 31 | 32 | describe "inspect" do 33 | it "includes all phone input attributes" do 34 | phone_input = described_class.new(phone_input_data) 35 | output = phone_input.inspect 36 | 37 | expect(output).to include("country_phone_code:\"1\"") 38 | expect(output).to include("phone_number:\"555-123-4567\"") 39 | expect(output).to include("extension_number:\"123\"") 40 | end 41 | 42 | it "includes only specified phone input attributes" do 43 | phone_input = described_class.new(partial_phone_input_data) 44 | output = phone_input.inspect 45 | 46 | expect(output).to include("country_phone_code:\"1\"") 47 | expect(output).to include("phone_number:\"555-123-4567\"") 48 | expect(output).not_to include("extension_number") 49 | end 50 | end 51 | end -------------------------------------------------------------------------------- /spec/unit/braintree/graphql_client_spec.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path(File.dirname(__FILE__) + "/../spec_helper") 2 | 3 | describe Braintree::GraphQLClient do 4 | 5 | describe ".get_validation_errors" do 6 | it "returns nil if no errors" do 7 | expect(Braintree::GraphQLClient.get_validation_errors({})).to be_nil 8 | end 9 | 10 | it "returns nil if errors is not an array" do 11 | expect(Braintree::GraphQLClient.get_validation_errors({:errors => "string"})).to be_nil 12 | end 13 | 14 | it "returns validation errors" do 15 | response = { 16 | :errors => [ 17 | {:message => "Invalid input", :extensions => {:legacyCode => "81803"}}, 18 | {:message => "Another error", :extensions => {:legacyCode => "91903"}} 19 | ] 20 | } 21 | expected_errors = { 22 | :errors => [ 23 | {:attribute => "", :code => "81803", :message => "Invalid input"}, 24 | {:attribute => "", :code => "91903", :message => "Another error"} 25 | ] 26 | } 27 | expect(Braintree::GraphQLClient.get_validation_errors(response)).to eq(expected_errors) 28 | end 29 | 30 | 31 | it "handles missing legacyCode" do 32 | response = {:errors => [{:message => "Invalid input"}]} 33 | expected_errors = {:errors => [{:attribute => "", :code => nil, :message => "Invalid input"}]} 34 | expect(Braintree::GraphQLClient.get_validation_errors(response)).to eq(expected_errors) 35 | end 36 | end 37 | end 38 | -------------------------------------------------------------------------------- /spec/unit/braintree/local_payment_expired_spec.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path(File.dirname(__FILE__) + "/../spec_helper") 2 | 3 | describe Braintree::LocalPaymentExpired do 4 | describe "self.new" do 5 | it "is protected" do 6 | expect do 7 | Braintree::LocalPaymentExpired.new 8 | end.to raise_error(NoMethodError, /protected method .new/) 9 | end 10 | end 11 | 12 | describe "self._new" do 13 | it "initializes the object with the appropriate attributes set" do 14 | params = { 15 | payment_id: "a-payment-id", 16 | payment_context_id: "a-payment-context-id", 17 | } 18 | local_payment_expired = Braintree::LocalPaymentExpired._new(params) 19 | 20 | expect(local_payment_expired.payment_id).to eq("a-payment-id") 21 | expect(local_payment_expired.payment_context_id).to eq("a-payment-context-id") 22 | end 23 | end 24 | end 25 | -------------------------------------------------------------------------------- /spec/unit/braintree/local_payment_funded_spec.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path(File.dirname(__FILE__) + "/../spec_helper") 2 | 3 | describe Braintree::LocalPaymentFunded do 4 | describe "self.new" do 5 | it "is protected" do 6 | expect do 7 | Braintree::LocalPaymentFunded.new 8 | end.to raise_error(NoMethodError, /protected method .new/) 9 | end 10 | end 11 | 12 | describe "self._new" do 13 | it "initializes the object with the appropriate attributes set" do 14 | params = { 15 | payment_id: "a-payment-id", 16 | payment_context_id: "a-payment-context-id", 17 | transaction: { 18 | id: "a-transaction-id", 19 | amount: "31.00", 20 | order_id: "an-order-id", 21 | status: Braintree::Transaction::Status::Settled, 22 | }, 23 | } 24 | local_payment_funded = Braintree::LocalPaymentFunded._new(params) 25 | 26 | expect(local_payment_funded.payment_id).to eq("a-payment-id") 27 | expect(local_payment_funded.payment_context_id).to eq("a-payment-context-id") 28 | expect(local_payment_funded.transaction.id).to eq("a-transaction-id") 29 | expect(local_payment_funded.transaction.amount).to eq(31.0) 30 | expect(local_payment_funded.transaction.order_id).to eq("an-order-id") 31 | expect(local_payment_funded.transaction.status).to eq(Braintree::Transaction::Status::Settled) 32 | end 33 | end 34 | end 35 | -------------------------------------------------------------------------------- /spec/unit/braintree/modification_spec.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path(File.dirname(__FILE__) + "/../spec_helper") 2 | 3 | describe Braintree::Modification do 4 | it "converts string amount" do 5 | expect(Braintree::Modification._new(:amount => "100.00").amount).to eq(BigDecimal("100.00")) 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /spec/unit/braintree/payment_method_customer_data_updated_metadata_spec.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path(File.dirname(__FILE__) + "/../spec_helper") 2 | 3 | describe Braintree::PaymentMethodCustomerDataUpdatedMetadata do 4 | describe "self.new" do 5 | it "is protected" do 6 | expect do 7 | Braintree::PaymentMethodCustomerDataUpdatedMetadata.new 8 | end.to raise_error(NoMethodError, /protected method .new/) 9 | end 10 | end 11 | 12 | describe "self._new" do 13 | it "initializes the object with the appropriate attributes set" do 14 | 15 | params = { 16 | token: "a-token", 17 | payment_method: { 18 | venmo_account: { 19 | venmo_user_id: "venmo-user-id", 20 | }, 21 | }, 22 | datetime_updated: "2022-01-01T21:28:37Z", 23 | enriched_customer_data: { 24 | fields_updated: ["username"], 25 | profile_data: { 26 | username: "a-username", 27 | first_name: "a-first-name", 28 | last_name: "a-last-name", 29 | phone_number: "a-phone-number", 30 | email: "a-email", 31 | }, 32 | }, 33 | } 34 | 35 | payment_method_customer_data_updated = Braintree::PaymentMethodCustomerDataUpdatedMetadata._new(:gateway, params) 36 | 37 | expect(payment_method_customer_data_updated.token).to eq("a-token") 38 | expect(payment_method_customer_data_updated.datetime_updated).to eq("2022-01-01T21:28:37Z") 39 | expect(payment_method_customer_data_updated.payment_method).to be_a(Braintree::VenmoAccount) 40 | expect(payment_method_customer_data_updated.enriched_customer_data.profile_data.first_name).to eq("a-first-name") 41 | expect(payment_method_customer_data_updated.enriched_customer_data.profile_data.last_name).to eq("a-last-name") 42 | expect(payment_method_customer_data_updated.enriched_customer_data.fields_updated).to eq(["username"]) 43 | end 44 | end 45 | end 46 | -------------------------------------------------------------------------------- /spec/unit/braintree/payment_method_nonce_details_payer_info_spec.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path(File.dirname(__FILE__) + "/../../spec_helper") 2 | 3 | describe Braintree::PaymentMethodNonceDetailsPayerInfo do 4 | let(:payment_method_nonce_details_payer_info) { 5 | Braintree::PaymentMethodNonceDetailsPayerInfo.new( 6 | :billing_agreement_id => "billing-agreement-id", 7 | :country_code => "US", 8 | :email => "test@example.com", 9 | :first_name => "First", 10 | :last_name => "Last", 11 | :payer_id => "payer-id", 12 | ) 13 | } 14 | 15 | describe "#initialize" do 16 | it "sets attributes" do 17 | expect(payment_method_nonce_details_payer_info.billing_agreement_id).to eq("billing-agreement-id") 18 | expect(payment_method_nonce_details_payer_info.country_code).to eq("US") 19 | expect(payment_method_nonce_details_payer_info.email).to eq("test@example.com") 20 | expect(payment_method_nonce_details_payer_info.first_name).to eq("First") 21 | expect(payment_method_nonce_details_payer_info.last_name).to eq("Last") 22 | expect(payment_method_nonce_details_payer_info.payer_id).to eq("payer-id") 23 | end 24 | end 25 | 26 | describe "inspect" do 27 | it "prints the attributes" do 28 | expect(payment_method_nonce_details_payer_info.inspect).to eq(%(#)) 29 | end 30 | end 31 | end 32 | -------------------------------------------------------------------------------- /spec/unit/braintree/payment_method_nonce_spec.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path(File.dirname(__FILE__) + "/../../spec_helper") 2 | 3 | describe Braintree::PaymentMethodNonce do 4 | let(:payment_method_nonce) { 5 | Braintree::PaymentMethodNonce._new( 6 | :gateway, 7 | :nonce => "some-nonce", 8 | :type => "CreditCard", 9 | :default => true, 10 | :details => { 11 | :bin => "some-bin" 12 | }, 13 | :three_d_secure_info => { 14 | :liability_shift_possible => false, 15 | :liability_shifted => false 16 | }, 17 | :bin_data => { 18 | :business => "No", 19 | :consumer => "No", 20 | :corporate => "No", 21 | :country_of_issuance => "USA", 22 | :prepaid_reloadable => "Yes", 23 | :purchase => "No", 24 | }, 25 | ) 26 | } 27 | 28 | describe "#initialize" do 29 | it "sets attributes" do 30 | expect(payment_method_nonce.nonce).to eq("some-nonce") 31 | expect(payment_method_nonce.type).to eq("CreditCard") 32 | expect(payment_method_nonce.default).to be true 33 | expect(payment_method_nonce.details.bin).to eq("some-bin") 34 | expect(payment_method_nonce.three_d_secure_info.liability_shift_possible).to be false 35 | expect(payment_method_nonce.three_d_secure_info.liability_shifted).to be false 36 | expect(payment_method_nonce.bin_data.business).to eq("No") 37 | expect(payment_method_nonce.bin_data.consumer).to eq("No") 38 | expect(payment_method_nonce.bin_data.corporate).to eq("No") 39 | expect(payment_method_nonce.bin_data.country_of_issuance).to eq("USA") 40 | expect(payment_method_nonce.bin_data.prepaid_reloadable).to eq("Yes") 41 | expect(payment_method_nonce.bin_data.purchase).to eq("No") 42 | end 43 | end 44 | 45 | describe "default" do 46 | it "is aliased to default?" do 47 | expect(payment_method_nonce.default?).to be true 48 | end 49 | end 50 | end 51 | -------------------------------------------------------------------------------- /spec/unit/braintree/risk_data/liability_shift.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path(File.dirname(__FILE__) + "/../../spec_helper") 2 | 3 | describe Braintree::Transaction::LiabilityShift do 4 | describe "#initialize" do 5 | it "sets responsible party and conditions" do 6 | liability_shift = Braintree::Transaction::LiabilityShift.new( 7 | :responsible_party => "paypal", 8 | :conditions => ["unauthorized","item_not_received"], 9 | ) 10 | 11 | expect(liability_shift.responsible_party).to eql "paypal" 12 | expect(liability_shift.conditions.first).to eql "unauthorized" 13 | end 14 | end 15 | 16 | describe "inspect" do 17 | it "prints the attributes" do 18 | details = Braintree::Transaction::LiabilityShift.new( 19 | :responsible_party => "paypal", 20 | :conditions => ["unauthorized","item_not_received"], 21 | ) 22 | 23 | expect(details.inspect).to eql %(#) 24 | end 25 | end 26 | end 27 | -------------------------------------------------------------------------------- /spec/unit/braintree/sepa_debit_account_nonce_details_spec.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path(File.dirname(__FILE__) + "/../../spec_helper") 2 | 3 | describe Braintree::SepaDirectDebitAccountNonceDetails do 4 | subject do 5 | described_class.new( 6 | :bank_reference_token => "a-bank-reference-token", 7 | :last_4 => "abcd", 8 | :mandate_type => "ONE_OFF", 9 | :merchant_or_partner_customer_id => "a-mp-customer-id", 10 | ) 11 | end 12 | 13 | describe "#initialize" do 14 | it "sets attributes" do 15 | is_expected.to have_attributes( 16 | :bank_reference_token => "a-bank-reference-token", 17 | :last_4 => "abcd", 18 | :mandate_type => "ONE_OFF", 19 | :merchant_or_partner_customer_id => "a-mp-customer-id", 20 | ) 21 | end 22 | end 23 | 24 | describe "inspect" do 25 | it "prints the attributes" do 26 | expect(subject.inspect).to eq(%(#)) 27 | end 28 | end 29 | end 30 | -------------------------------------------------------------------------------- /spec/unit/braintree/sha256_digest_spec.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path(File.dirname(__FILE__) + "/../spec_helper") 2 | 3 | describe Braintree::SHA256Digest do 4 | describe "self.hexdigest" do 5 | it "returns the sha256 hmac of the input string (test case 6 from RFC 2202)" do 6 | key = "secret-key" 7 | message = "secret-message" 8 | expect(Braintree::SHA256Digest.hexdigest(key, message)).to eq("68e7f2ecab71db67b1aca2a638f5122810315c3013f27c2196cd53e88709eecc") 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /spec/unit/braintree/signature_service_spec.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path(File.dirname(__FILE__) + "/../spec_helper") 2 | 3 | class FakeDigest 4 | def self.hexdigest(key, string) 5 | "#{string}_signed_with_#{key}" 6 | end 7 | end 8 | 9 | describe Braintree::SignatureService do 10 | describe "sign" do 11 | it "signs the data with its key" do 12 | service = Braintree::SignatureService.new("my_key", FakeDigest) 13 | 14 | expect(service.sign(:foo => "foo bar")).to eq("foo=foo+bar_signed_with_my_key|foo=foo+bar") 15 | end 16 | end 17 | 18 | describe "hash" do 19 | it "hashes the string with its key" do 20 | expect(Braintree::SignatureService.new("my_key", FakeDigest).hash("foo")).to eq("foo_signed_with_my_key") 21 | end 22 | end 23 | end 24 | -------------------------------------------------------------------------------- /spec/unit/braintree/successful_result_spec.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path(File.dirname(__FILE__) + "/../spec_helper") 2 | 3 | describe Braintree::SuccessfulResult do 4 | describe "initialize" do 5 | it "sets instance variables from the values in the hash" do 6 | result = Braintree::SuccessfulResult.new( 7 | :transaction => "transaction_value", 8 | :credit_card => "credit_card_value", 9 | ) 10 | expect(result.success?).to eq(true) 11 | expect(result.transaction).to eq("transaction_value") 12 | expect(result.credit_card).to eq("credit_card_value") 13 | end 14 | 15 | it "can be initialized without any values" do 16 | result = Braintree::SuccessfulResult.new 17 | expect(result.success?).to eq(true) 18 | end 19 | end 20 | 21 | describe "inspect" do 22 | it "is pretty" do 23 | result = Braintree::SuccessfulResult.new(:transaction => "transaction_value") 24 | expect(result.inspect).to eq("#") 25 | end 26 | end 27 | end 28 | -------------------------------------------------------------------------------- /spec/unit/braintree/transaction/apple_pay_details_spec.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path(File.dirname(__FILE__) + "/../spec_helper") 2 | 3 | describe Braintree::ApplePayDetails do 4 | it "initializes prepaid reloadable correctly" do 5 | card = Braintree::ApplePayDetails._new(:gateway, {:prepaid_reloadable => "No"}) 6 | expect(card.prepaid_reloadable).to eq("No") 7 | end 8 | 9 | it "initializes business correctly" do 10 | card = Braintree::ApplePayDetails._new(:gateway, {:business => "No"}) 11 | expect(card.business).to eq("No") 12 | end 13 | 14 | it "initializes consumer correctly" do 15 | card = Braintree::ApplePayDetails._new(:gateway, {:consumer => "No"}) 16 | expect(card.consumer).to eq("No") 17 | end 18 | 19 | it "initializes corporate correctly" do 20 | card = Braintree::ApplePayDetails._new(:gateway, {:corporate => "No"}) 21 | expect(card.corporate).to eq("No") 22 | end 23 | 24 | it "initializes purchase correctly" do 25 | card = Braintree::ApplePayDetails._new(:gateway, {:purchase => "No"}) 26 | expect(card.purchase).to eq("No") 27 | end 28 | end 29 | -------------------------------------------------------------------------------- /spec/unit/braintree/transaction/customer_details_spec.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path(File.dirname(__FILE__) + "/../../spec_helper") 2 | 3 | describe Braintree::Transaction::CustomerDetails do 4 | describe "inspect" do 5 | it "inspects" do 6 | details = Braintree::Transaction::CustomerDetails.new( 7 | :id => "id", 8 | :first_name => "Amy", 9 | :last_name => "Smith", 10 | :email => "amy.smith@example.com", 11 | :company => "Smith Co.", 12 | :website => "http://www.example.com", 13 | :phone => "6145551234", 14 | :international_phone => {:country_code=>"1", :national_number=>"3121234567"}, 15 | :fax => "3125551234", 16 | ) 17 | expect(details.inspect).to eq(%(#\"1\", :national_number=>\"3121234567\"}, fax: "3125551234">)) 18 | end 19 | end 20 | end 21 | -------------------------------------------------------------------------------- /spec/unit/braintree/transaction/deposit_details_spec.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path(File.dirname(__FILE__) + "/../../spec_helper") 2 | 3 | describe Braintree::Transaction::DisbursementDetails do 4 | describe "valid?" do 5 | it "returns true if disbursement details are initialized" do 6 | details = Braintree::Transaction::DisbursementDetails.new( 7 | :disbursement_date => Date.new(2013, 4, 1).to_s, 8 | ) 9 | expect(details.valid?).to eq(true) 10 | end 11 | it "returns true if disbursement details are initialized" do 12 | details = Braintree::Transaction::DisbursementDetails.new( 13 | :disbursement_date => nil, 14 | ) 15 | expect(details.valid?).to eq(false) 16 | end 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /spec/unit/braintree/transaction/google_pay_details_spec.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path(File.dirname(__FILE__) + "/../spec_helper") 2 | 3 | describe Braintree::GooglePayDetails do 4 | it "initializes prepaid reloadable correctly" do 5 | card = Braintree::GooglePayDetails._new(:gateway, {:prepaid_reloadable => "No"}) 6 | expect(card.prepaid_reloadable).to eq("No") 7 | end 8 | 9 | it "initializes business correctly" do 10 | card = Braintree::GooglePayDetails._new(:gateway, {:business => "No"}) 11 | expect(card.business).to eq("No") 12 | end 13 | 14 | it "initializes consumer correctly" do 15 | card = Braintree::GooglePayDetails._new(:gateway, {:consumer => "No"}) 16 | expect(card.consumer).to eq("No") 17 | end 18 | 19 | it "initializes corporate correctly" do 20 | card = Braintree::GooglePayDetails._new(:gateway, {:corporate => "No"}) 21 | expect(card.corporate).to eq("No") 22 | end 23 | 24 | it "initializes purchase correctly" do 25 | card = Braintree::GooglePayDetails._new(:gateway, {:purchase => "No"}) 26 | expect(card.purchase).to eq("No") 27 | end 28 | end 29 | -------------------------------------------------------------------------------- /spec/unit/braintree/transaction/installment_spec.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path(File.dirname(__FILE__) + "/../../spec_helper") 2 | 3 | describe Braintree::Transaction::Installment do 4 | describe "inspect" do 5 | it "assigns all fields" do 6 | adjustment_attributes = { 7 | :amount => "0.98", 8 | :kind => "REFUND", 9 | :projected_disbursement_date => "2020-01-03 01:02:03Z", 10 | :actual_disbursement_date => "2020-01-04 01:02:03Z", 11 | } 12 | installment_attributes = { 13 | :id => "abc123", 14 | :amount => "1.23", 15 | :projected_disbursement_date => "2020-01-01 01:02:03Z", 16 | :actual_disbursement_date => "2020-01-02 01:02:03Z", 17 | :adjustments => [adjustment_attributes], 18 | } 19 | 20 | installment = Braintree::Transaction::Installment.new(installment_attributes) 21 | 22 | expect(installment.inspect).to eq('#]>') 23 | end 24 | end 25 | end 26 | -------------------------------------------------------------------------------- /spec/unit/braintree/transaction/local_payment_details_spec.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path(File.dirname(__FILE__) + "/../../spec_helper") 2 | 3 | describe Braintree::Transaction::LocalPaymentDetails do 4 | describe "initialize" do 5 | let(:params) do 6 | { 7 | blik_aliases: [ 8 | { 9 | key: "a-key", 10 | label: "a-label" 11 | } 12 | ], 13 | capture_id: "a-capture-id", 14 | custom_field: "custom-field", 15 | debug_id: "debug-id", 16 | description: "description", 17 | funding_source: "ideal", 18 | implicitly_vaulted_payment_method_global_id: "global-id", 19 | implicitly_vaulted_payment_method_token: "payment-method-token", 20 | payer_id: "payer-id", 21 | payment_id: "payment-id", 22 | refund_from_transaction_fee_amount: "2.34", 23 | refund_from_transaction_fee_currency_iso_code: "EUR", 24 | refund_id: "a-refund-id", 25 | transaction_fee_amount: "12.34", 26 | transaction_fee_currency_iso_code: "EUR", 27 | } 28 | end 29 | 30 | subject { described_class.new(params) } 31 | 32 | it "sets all fields" do 33 | is_expected.to have_attributes(**params) 34 | end 35 | end 36 | end 37 | -------------------------------------------------------------------------------- /spec/unit/braintree/transaction/meta_checkout_card_details_spec.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path(File.dirname(__FILE__) + "/../spec_helper") 2 | 3 | describe Braintree::MetaCheckoutCardDetails do 4 | it "initializes prepaid reloadable correctly" do 5 | card = Braintree::MetaCheckoutCardDetails._new(:gateway, {:prepaid_reloadable => "No"}) 6 | expect(card.prepaid_reloadable).to eq("No") 7 | end 8 | 9 | it "initializes business correctly" do 10 | card = Braintree::MetaCheckoutCardDetails._new(:gateway, {:business => "No"}) 11 | expect(card.business).to eq("No") 12 | end 13 | 14 | it "initializes consumer correctly" do 15 | card = Braintree::MetaCheckoutCardDetails._new(:gateway, {:consumer => "No"}) 16 | expect(card.consumer).to eq("No") 17 | end 18 | 19 | it "initializes corporate correctly" do 20 | card = Braintree::MetaCheckoutCardDetails._new(:gateway, {:corporate => "No"}) 21 | expect(card.corporate).to eq("No") 22 | end 23 | 24 | it "initializes purchase correctly" do 25 | card = Braintree::MetaCheckoutCardDetails._new(:gateway, {:purchase => "No"}) 26 | expect(card.purchase).to eq("No") 27 | end 28 | end 29 | -------------------------------------------------------------------------------- /spec/unit/braintree/transaction/meta_checkout_token_details_spec.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path(File.dirname(__FILE__) + "/../spec_helper") 2 | 3 | describe Braintree::MetaCheckoutTokenDetails do 4 | it "initializes prepaid reloadable correctly" do 5 | card = Braintree::MetaCheckoutTokenDetails._new(:gateway, {:prepaid_reloadable => "No"}) 6 | expect(card.prepaid_reloadable).to eq("No") 7 | end 8 | 9 | it "initializes business correctly" do 10 | card = Braintree::MetaCheckoutTokenDetails._new(:gateway, {:business => "No"}) 11 | expect(card.business).to eq("No") 12 | end 13 | 14 | it "initializes consumer correctly" do 15 | card = Braintree::MetaCheckoutTokenDetails._new(:gateway, {:consumer => "No"}) 16 | expect(card.consumer).to eq("No") 17 | end 18 | 19 | it "initializes corporate correctly" do 20 | card = Braintree::MetaCheckoutTokenDetails._new(:gateway, {:corporate => "No"}) 21 | expect(card.corporate).to eq("No") 22 | end 23 | 24 | it "initializes purchase correctly" do 25 | card = Braintree::MetaCheckoutTokenDetails._new(:gateway, {:purchase => "No"}) 26 | expect(card.purchase).to eq("No") 27 | end 28 | end 29 | -------------------------------------------------------------------------------- /spec/unit/braintree/transaction/sepa_direct_debit_account_details_spec.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path(File.dirname(__FILE__) + "/../../spec_helper") 2 | 3 | describe Braintree::Transaction::SepaDirectDebitAccountDetails do 4 | describe "initialize" do 5 | let(:params) do 6 | { 7 | bank_reference_token: "a-reference-token", 8 | capture_id: "a-capture-id", 9 | debug_id: "a-debug-id", 10 | global_id: "a-global-id", 11 | last_4: "1234", 12 | mandate_type: "ONE_OFF", 13 | merchant_or_partner_customer_id: "12312312343", 14 | paypal_v2_order_id: "a-paypal-v2-order-id", 15 | refund_from_transaction_fee_amount: "2.34", 16 | refund_from_transaction_fee_currency_iso_code: "EUR", 17 | refund_id: "a-refund-id", 18 | settlement_type: "INSTANT", 19 | token: "a-token", 20 | transaction_fee_amount: "12.34", 21 | transaction_fee_currency_iso_code: "EUR", 22 | } 23 | end 24 | 25 | subject do 26 | described_class.new(params) 27 | end 28 | 29 | it "sets all fields" do 30 | is_expected.to have_attributes(**params) 31 | end 32 | end 33 | end 34 | -------------------------------------------------------------------------------- /spec/unit/braintree/transaction/visa_checkout_card_details_spec.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path(File.dirname(__FILE__) + "/../spec_helper") 2 | 3 | describe Braintree::VisaCheckoutCardDetails do 4 | it "initializes prepaid reloadable correctly" do 5 | card = Braintree::VisaCheckoutCardDetails._new(:gateway, {:prepaid_reloadable => "No"}) 6 | expect(card.prepaid_reloadable).to eq("No") 7 | end 8 | 9 | it "initializes business correctly" do 10 | card = Braintree::VisaCheckoutCardDetails._new(:gateway, {:business => "No"}) 11 | expect(card.business).to eq("No") 12 | end 13 | 14 | it "initializes consumer correctly" do 15 | card = Braintree::VisaCheckoutCardDetails._new(:gateway, {:consumer => "No"}) 16 | expect(card.consumer).to eq("No") 17 | end 18 | 19 | it "initializes corporate correctly" do 20 | card = Braintree::VisaCheckoutCardDetails._new(:gateway, {:corporate => "No"}) 21 | expect(card.corporate).to eq("No") 22 | end 23 | 24 | it "initializes purchase correctly" do 25 | card = Braintree::VisaCheckoutCardDetails._new(:gateway, {:purchase => "No"}) 26 | expect(card.purchase).to eq("No") 27 | end 28 | end 29 | -------------------------------------------------------------------------------- /spec/unit/braintree/transaction_search_spec.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path(File.dirname(__FILE__) + "/../spec_helper") 2 | 3 | describe Braintree::TransactionSearch do 4 | it "overrides previous 'is' with new 'is' for the same field" do 5 | search = Braintree::TransactionSearch.new 6 | search.billing_company.is "one" 7 | search.billing_company.is "two" 8 | expect(search.to_hash).to eq({:billing_company => {:is => "two"}}) 9 | end 10 | 11 | it "overrides previous 'in' with new 'in' for the same field" do 12 | search = Braintree::TransactionSearch.new 13 | search.status.in Braintree::Transaction::Status::Authorized 14 | search.status.in Braintree::Transaction::Status::SubmittedForSettlement 15 | expect(search.to_hash).to eq({:status => [Braintree::Transaction::Status::SubmittedForSettlement]}) 16 | end 17 | 18 | it "raises if the operator 'is' is left off" do 19 | search = Braintree::TransactionSearch.new 20 | expect do 21 | search.billing_company "one" 22 | end.to raise_error(RuntimeError, "An operator is required") 23 | end 24 | end 25 | -------------------------------------------------------------------------------- /spec/unit/braintree/unknown_payment_method_spec.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path(File.dirname(__FILE__) + "/../spec_helper") 2 | 3 | describe Braintree::PayPalAccount do 4 | before(:each) do 5 | @gateway = OpenStruct.new() 6 | end 7 | 8 | describe "token" do 9 | it "has a token identifier" do 10 | params = {:unknown_payment_method => {:token => 1234, :default => true}} 11 | expect(Braintree::UnknownPaymentMethod.new(@gateway, params).token).to eq(1234) 12 | end 13 | end 14 | 15 | describe "image_url" do 16 | it "has a image_url" do 17 | params = {:unknown_payment_method => {:token => 1234, :default => true}} 18 | expect(Braintree::UnknownPaymentMethod.new(@gateway, params).image_url).to eq("https://assets.braintreegateway.com/payment_method_logo/unknown.png") 19 | end 20 | end 21 | 22 | describe "default?" do 23 | it "is true if the paypal account is the default payment method for the customer" do 24 | params = {:unknown_payment_method => {:token => 1234, :default => true}} 25 | expect(Braintree::UnknownPaymentMethod.new(@gateway, params)).to be_default 26 | end 27 | 28 | it "is false if the paypal account is not the default payment methodfor the customer" do 29 | params = {:unknown_payment_method => {:token => 1234, :default => false}} 30 | expect(Braintree::UnknownPaymentMethod.new(@gateway, params)).not_to be_default 31 | end 32 | end 33 | end 34 | -------------------------------------------------------------------------------- /spec/unit/braintree/us_bank_account_spec.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path(File.dirname(__FILE__) + "/../spec_helper") 2 | 3 | describe Braintree::UsBankAccount do 4 | describe "default?" do 5 | it "is true if the us bank account is the default us bank account for the customer" do 6 | expect(Braintree::UsBankAccount._new(:gateway, :default => true).default?).to eq(true) 7 | end 8 | 9 | it "is false if the us bank account is not the default us bank account for the customer" do 10 | expect(Braintree::UsBankAccount._new(:gateway, :default => false).default?).to eq(false) 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /spec/unit/braintree/validation_error_spec.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path(File.dirname(__FILE__) + "/../spec_helper") 2 | 3 | describe Braintree::ValidationError do 4 | describe "initialize" do 5 | it "works" do 6 | error = Braintree::ValidationError.new :attribute => "some model attribute", :code => 1, :message => "bad juju" 7 | expect(error.attribute).to eq("some model attribute") 8 | expect(error.code).to eq(1) 9 | expect(error.message).to eq("bad juju") 10 | end 11 | end 12 | 13 | describe "inspect" do 14 | it "is pretty" do 15 | error = Braintree::ValidationError.new :attribute => "number", :code => "123456", :message => "Number is bad juju." 16 | expect(error.inspect).to eq("#") 17 | end 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /spec/unit/braintree/venmo_profile_data_spec.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path(File.dirname(__FILE__) + "/../spec_helper") 2 | 3 | describe Braintree::VenmoProfileData do 4 | describe "self.new" do 5 | it "is protected" do 6 | expect do 7 | Braintree::VenmoProfileData.new 8 | end.to raise_error(NoMethodError, /protected method .new/) 9 | end 10 | end 11 | 12 | describe "self._new" do 13 | it "initializes the object with the appropriate attributes set" do 14 | 15 | address = { 16 | street_address: "a-street-address", 17 | extended_address: "an-extended-address", 18 | locality: "a-locality", 19 | region: "a-region", 20 | postal_code: "a-postal-code" 21 | } 22 | params = { 23 | username: "a-username", 24 | first_name: "a-first-name", 25 | last_name: "a-last-name", 26 | phone_number: "12312312343", 27 | email: "a-email", 28 | billing_address: address, 29 | shipping_address: address 30 | } 31 | 32 | payment_method_customer_data_updated = Braintree::VenmoProfileData._new(params) 33 | 34 | expect(payment_method_customer_data_updated.username).to eq("a-username") 35 | expect(payment_method_customer_data_updated.first_name).to eq("a-first-name") 36 | expect(payment_method_customer_data_updated.last_name).to eq("a-last-name") 37 | expect(payment_method_customer_data_updated.phone_number).to eq("12312312343") 38 | expect(payment_method_customer_data_updated.email).to eq("a-email") 39 | expect(payment_method_customer_data_updated.billing_address).to eq(address) 40 | expect(payment_method_customer_data_updated.shipping_address).to eq(address) 41 | end 42 | end 43 | end 44 | -------------------------------------------------------------------------------- /spec/unit/braintree/visa_checkout_card_spec.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path(File.dirname(__FILE__) + "/../spec_helper") 2 | 3 | describe Braintree::VisaCheckoutCard do 4 | it "initializes prepaid reloadable correctly" do 5 | card = Braintree::VisaCheckoutCard._new(:gateway, {:prepaid_reloadable => "No"}) 6 | expect(card.prepaid_reloadable).to eq("No") 7 | end 8 | 9 | it "initializes business correctly" do 10 | card = Braintree::VisaCheckoutCard._new(:gateway, {:business => "No"}) 11 | expect(card.business).to eq("No") 12 | end 13 | 14 | it "initializes consumer correctly" do 15 | card = Braintree::VisaCheckoutCard._new(:gateway, {:consumer => "No"}) 16 | expect(card.consumer).to eq("No") 17 | end 18 | 19 | it "initializes corporate correctly" do 20 | card = Braintree::VisaCheckoutCard._new(:gateway, {:corporate => "No"}) 21 | expect(card.corporate).to eq("No") 22 | end 23 | 24 | it "initializes purchase correctly" do 25 | card = Braintree::VisaCheckoutCard._new(:gateway, {:purchase => "No"}) 26 | expect(card.purchase).to eq("No") 27 | end 28 | end 29 | -------------------------------------------------------------------------------- /spec/unit/braintree/xml/rexml_spec.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path(File.dirname(__FILE__) + "/../../spec_helper") 2 | 3 | describe Braintree::Xml::Rexml do 4 | describe "self.parse" do 5 | it "typecasts integers" do 6 | xml = "123" 7 | expect(Braintree::Xml::Rexml.parse(xml)).to eq({"root"=>{"foo"=>{"__content__"=>"123", "type"=>"integer"}}}) 8 | end 9 | 10 | it "works with dashes or underscores" do 11 | xml = <<-END 12 | 13 | 14 | 15 | 16 | END 17 | expect(Braintree::Xml::Rexml.parse(xml)).to eq({"root"=>{"dash-es"=>{}, "under_scores"=>{}}}) 18 | end 19 | 20 | it "uses nil if nil=true, otherwise uses empty string" do 21 | xml = <<-END 22 | 23 | 24 | 25 | 26 | END 27 | expect(Braintree::Xml::Rexml.parse(xml)).to eq({"root"=>{"a_nil_value"=>{"nil"=>"true"}, "an_empty_string"=>{}}}) 28 | end 29 | 30 | it "typecasts dates and times" do 31 | xml = <<-END 32 | 33 | 2009-10-28T10:19:49Z 34 | 35 | END 36 | expect(Braintree::Xml::Rexml.parse(xml)).to eq({"root"=>{"created-at"=>{"__content__"=>"2009-10-28T10:19:49Z", "type"=>"datetime"}}}) 37 | end 38 | 39 | it "builds an array if type=array" do 40 | xml = <<-END 41 | 42 | 43 | Adam 44 | Ben 45 | 46 | 47 | END 48 | expect(Braintree::Xml::Rexml.parse(xml)).to eq({"root"=>{"customers"=>{"type"=>"array", "customer"=>[{"name"=>{"__content__"=>"Adam"}}, {"name"=>{"__content__"=>"Ben"}}]}}}) 49 | end 50 | end 51 | end 52 | -------------------------------------------------------------------------------- /spec/unit/braintree_spec.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path(File.dirname(__FILE__) + "/spec_helper") 2 | 3 | describe Braintree do 4 | it "doesn't produce warnings if loading braintree.rb twice" do 5 | lib_dir = File.expand_path(File.dirname(__FILE__) + "/../../lib") 6 | braintree_file = "#{lib_dir}/braintree.rb" 7 | expect(File.exist?(braintree_file)).to eq(true) 8 | output = `ruby -r rubygems -I #{lib_dir} -e 'load #{braintree_file.inspect}; load #{braintree_file.inspect}' 2>&1` 9 | output = output.gsub(/^.*warning: constant ::Fixnum is deprecated.*\n/, "") 10 | expect(output).to eq("") 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /spec/unit/credit_card_details_spec.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path(File.dirname(__FILE__) + "/../spec_helper") 2 | 3 | describe Braintree::CreditCardDetails do 4 | it "initializes prepaid reloadable correctly" do 5 | card = Braintree::CreditCardDetails._new(:gateway, {:prepaid_reloadable => "No"}) 6 | expect(card.prepaid_reloadable).to eq("No") 7 | end 8 | 9 | it "initializes business correctly" do 10 | card = Braintree::CreditCardDetails._new(:gateway, {:business => "No"}) 11 | expect(card.business).to eq("No") 12 | end 13 | 14 | it "initializes consumer correctly" do 15 | card = Braintree::CreditCardDetails._new(:gateway, {:consumer => "No"}) 16 | expect(card.consumer).to eq("No") 17 | end 18 | 19 | it "initializes corporate correctly" do 20 | card = Braintree::CreditCardDetails._new(:gateway, {:corporate => "No"}) 21 | expect(card.corporate).to eq("No") 22 | end 23 | 24 | it "initializes purchase correctly" do 25 | card = Braintree::CreditCardDetails._new(:gateway, {:purchase => "No"}) 26 | expect(card.purchase).to eq("No") 27 | end 28 | end 29 | -------------------------------------------------------------------------------- /spec/unit/spec_helper.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path(File.dirname(__FILE__) + "/../spec_helper") 2 | --------------------------------------------------------------------------------