{"id":20779121,"url":"https://github.com/solidusio/solidus_affirm","last_synced_at":"2025-04-30T19:41:17.279Z","repository":{"id":37964137,"uuid":"74054073","full_name":"solidusio/solidus_affirm","owner":"solidusio","description":"Affirm payment option for your Solidus storefront","archived":false,"fork":false,"pushed_at":"2023-10-06T16:02:12.000Z","size":176,"stargazers_count":6,"open_issues_count":7,"forks_count":17,"subscribers_count":15,"default_branch":"main","last_synced_at":"2025-03-30T19:22:08.691Z","etag":null,"topics":["affirm","ecommerce","ecommerce-platform","hacktoberfest","payment","payment-gateway","solidus-extensions"],"latest_commit_sha":null,"homepage":"","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/solidusio.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null},"funding":{"open_collective":"solidus"}},"created_at":"2016-11-17T18:09:45.000Z","updated_at":"2024-08-02T02:20:39.000Z","dependencies_parsed_at":"2024-02-24T19:51:36.372Z","dependency_job_id":null,"html_url":"https://github.com/solidusio/solidus_affirm","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/solidusio%2Fsolidus_affirm","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/solidusio%2Fsolidus_affirm/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/solidusio%2Fsolidus_affirm/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/solidusio%2Fsolidus_affirm/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/solidusio","download_url":"https://codeload.github.com/solidusio/solidus_affirm/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251770932,"owners_count":21641176,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["affirm","ecommerce","ecommerce-platform","hacktoberfest","payment","payment-gateway","solidus-extensions"],"created_at":"2024-11-17T13:26:07.544Z","updated_at":"2025-04-30T19:41:17.255Z","avatar_url":"https://github.com/solidusio.png","language":"Ruby","funding_links":["https://opencollective.com/solidus"],"categories":[],"sub_categories":[],"readme":"# SolidusAffirm\n\n[![CircleCI](https://circleci.com/gh/solidusio/solidus_affirm.svg?style=svg)](https://circleci.com/gh/solidusio/solidus_affirm)\n\nThis extension provides the [Affirm](https://www.affirm.com/) payment option\nfor your Solidus storefront by implementing the [Affirm Direct API](https://docs.affirm.com/Integrate_Affirm/Direct_API)\n\nThere is additional documenation available at the [Affirm documentation website](https://docs.affirm.com/Integrate_Affirm/Platform_Integration/Solidus_Integration)\n\n## Installation\n\nAdd solidus_affirm to your Gemfile:\n\n```ruby\ngem 'solidus_affirm', github: 'solidusio-contrib/solidus_affirm'\n```\n\nBundle your dependencies and run the installation generator:\n\n```shell\nbundle\nbundle exec rails g solidus_affirm:install\n```\n## Configuration\n\nTo generate the correct URL's in the JSON payload we need to specify the\n`default_url_options` for the Solidus engine. You can do that like this:\n\n```\nSpree::Core::Engine.routes.default_url_options = {\n  host: 'example.com'\n}\n```\n\nYou will need to get your public and private API keys from the Affirm Dashboard, see the [Affirm Documentation](https://docs.affirm.com/Integrate_Affirm/Direct_API).\n\n* Sandbox = https://sandbox.affirm.com/dashboard\n* Live = https://affirm.com/dashboard\n\nWhen you configure the payment gateway you need to provide those keys to\nthe payment gateway and also the link to the Affirm JS Runtime script.\n\nMake sure that during development and testing you use the sandbox version:\n* Sandbox = https://cdn1-sandbox.affirm.com/js/v2/affirm.js\n* Live = https://cdn1.affirm.com/js/v2/affirm.js\n\n### Configure via database configuration\n\nIf you want to store your Affirm credentials in the database just\nfill the new fields in the form, selecting `custom` (default) in the\nPreference Source field.\n\n### Configure via static configuration\n\nIf you want to store your credentials into your codebase or use ENV\nvariables you can create the following static configuration:\n\n```ruby\n# config/initializers/spree.rb\n\nSpree.config do |config|\n  # ...\n  config.static_model_preferences.add(\n    SolidusAffirm::Gateway,\n    'affirm_env_credentials',\n    public_api_key: ENV['AFFIRM_PUBLIC_KEY'],\n    private_api_key: ENV['AFFIRM_PRIVATE_KEY'],\n    javascript_url: ENV['AFFIRM_JS_RUNTIME_URL'],\n    test_mode: !Rails.env.production?\n  )\nend\n```\n\nOnce your server has been restarted, you can select `affirm_env_credentials` in\nthe Preference Source field. After saving, your application will start using the\nstatic configuration to process Affirm payments.\n\n## Hooks and extension points\n\nWe provide a configuration class the allows you customize the complete setup.\n\nTo do so, you can use the `SolidusAffirm::Config` class in an initializer,\nlike `config/initializers/spree.rb` for example.\n\n### Callback controller\n\nWhen performing a checkout on Affirm, there are 2 callbacks that Affirm\ncould send to our system.\n\n1) a `POST` to the `confirm` action.\n2) a `GET` to the `cancel` action.\n\nTo change the controller that is handling those actions you can specify\nthe route name like this:\n\n```ruby\nSolidusAffirm::Config.callback_controller_name = 'my_custom_affirm'\n```\n\nSince the routes file here is within the `Spree` namespace you will have to\nprovide the controller in that namespace. So with the above sample, `my_controller`,\nyou should define a controller like this:\n\n```ruby\nclass Spree::MyCustomAffirmController \u003c Spree::StoreController\n  def confirm\n    #implement your own confirm action here.\n  end\n\n  def cancel\n    #implement your own cancel action here.\n  end\nend\n```\n\nNote that you could inherit from the provided controller as well if you\njust want to override one part. The default controller we have setup here\nis `Spree::AffirmController`.\n\nIf you just need to change the way you like to handle the confirm and cancel\nactions, read below. We provide a hook for that as well.\n\n### Callback flow for confirming and canceling\n\nFor confirming or canceling an Affirm payment we provide sane defaults for\nthat in the `SolidusAffirm::CallbackHook::Base` class.\n\nThat class provides 3 methods that we use in the controller for:\n* setup the payment on the order correctly and use the checkout state_machine\n* the redirect url after the confirm action is done\n* the redirect url after the cancel action\n\nTo change that behaviour you can provide your own callback hook class like this:\n\n```ruby\nclass MyCallbackHook \u003c SolidusAffirm::CallbackHook::Base\n  def authorize!(payment)\n    #do your magic here.\n  end\n\n  def after_authorize_url(order)\n    'sample/endpoint/success'\n  end\n\n  def after_cancel_url(order)\n    'sample/endpoint/cancel'\n  end\nend\n```\n\nThen configure this class name in an initializer like this:\n\n```ruby\nSolidusAffirm::Config.callback_hook = MyCallbackHook\n```\n\n### Checkout payload serializer\n\nTo generate the JSON payload for the order that Affirm needs to setup the\npayment we provide a default serializer in `SolidusAffirm::CheckoutPayloadSerializer`.\n\nYou can change that by providing your custom serializer. If you just need to\noverride a few attributes you should inherit from `SolidusAffirm::CheckoutPayloadSerializer` and just provide the implementations of the\nattributes you would like to change. The untouched attributes will be inherited by default.\n\nFor example, to just override the shipping attribute you can do something like this:\n\n```ruby\nclass MyCustomPayloadSerializer \u003c SolidusAffirm::CheckoutPayloadSerializer\n  def shipping\n    MyCustomAddressSerializerImpl(object.ship_address)\n  end\nend\n```\n\nThen configure this new class to be the serializer:\n\n```ruby\nSolidusAffirm::Config.checkout_payload_serializer = MyCustomPayloadSerializer\n```\n\n## Testing\n\nFirst bundle your dependencies, then run `rake`. `rake` will default to building the dummy app if it does not exist, then it will run specs, and [Rubocop](https://github.com/bbatsov/rubocop) static code analysis. The dummy app can be regenerated by using `rake extension:test_app`.\n\n```shell\nbundle\nbundle exec rake\n```\n\nWhen testing your applications integration with this extension you may use it's factories.\nSimply add this require statement to your spec_helper:\n\n```ruby\nrequire 'solidus_affirm/factories'\n```\n\nCopyright (c) 2018 Stembolt, released under the New BSD License\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsolidusio%2Fsolidus_affirm","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsolidusio%2Fsolidus_affirm","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsolidusio%2Fsolidus_affirm/lists"}