Last active
August 20, 2019 16:12
-
-
Save drewish/b1a562e2c99060dc2ab6fad9d093b7dc to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# This is a script to demonstrate some features of Recurly's V3 API. It shows | |
# how to use multiple clients for separate sites to copy plan and add-on data | |
# between them. | |
require 'bundler/inline' | |
gemfile do | |
source 'https://rubygems.org' | |
gem 'recurly', '3.0.0.beta.6' | |
gem 'pry' | |
end | |
SOURCE_API_KEY = '?' | |
SOURCE_SITE_ID = '?' | |
DESTINATION_API_KEY = '?' | |
DESTINATION_SITE_ID = '?' | |
PLAN_ATTRIBUTES = %i( | |
code name description interval_unit interval_length trial_unit trial_length | |
total_billing_cycles auto_renew accounting_code setup_fee_accounting_code | |
tax_code tax_exempt | |
) | |
ADD_ON_ATTRIBUTES = %i( | |
code name display_quantity default_quantity accounting_code tax_code | |
) | |
source_client = Recurly::Client.new(api_key: SOURCE_API_KEY, site_id: SOURCE_SITE_ID) | |
destination_client = Recurly::Client.new(api_key: DESTINATION_API_KEY, site_id: DESTINATION_SITE_ID) | |
puts "Copying plans and add-ons from '#{source_client.get_site.subdomain}' to '#{destination_client.get_site.subdomain}'" | |
# We can track the mappings here... might not be necessary. | |
plan_map = {} | |
source_client.list_plans(state: :active).each do |source_plan| | |
# Some of the attributes are read-only and cannot be assigned during creation | |
# this is all we'll copy over. We need the `compact` call to get rid of any | |
# `nil` values. | |
attributes = source_plan.attributes.slice(*PLAN_ATTRIBUTES).compact | |
# The pricing in the currencies structure is more complicated and needs a | |
# litte extra attention. | |
attributes[:currencies] = source_plan.currencies.map(&:attributes) | |
# A plan might already exist in the destination site and we'd need to update | |
# it rather than create a new one. We could either check if it exists and then | |
# do a create or update... or we could just try the create and if it says it | |
# already exists do an update. We'll demonstrate the former for plans and the | |
# later for the add-ons | |
begin | |
# We don't actually need the response we're just checking if it exists. | |
destination_client.get_plan(plan_id: "code-#{source_plan.code}") | |
# Sadly, we can't change the interval_unit or interval_length of an existing | |
# plan so we'll have to exclude those from updates. The only way to change | |
# them is to delete the plan and recreate it. | |
attributes.delete(:interval_unit) | |
attributes.delete(:interval_length) | |
destination_plan = destination_client.update_plan( | |
plan_id: "code-#{source_plan.code}", | |
body: attributes | |
) | |
puts "Updated plan '#{destination_plan.code}'" | |
plan_map[source_plan.id] = destination_plan.id | |
rescue Recurly::Errors::NotFoundError => ex | |
destination_plan = destination_client.create_plan(body: attributes) | |
puts "Created plan '#{destination_plan.code}'" | |
plan_map[source_plan.id] = destination_plan.id | |
end | |
end | |
source_client.list_add_ons(state: :active).each do |source_add_on| | |
# Now we need to use the plan_map we built that tracks how the source and | |
# destination plans are related. If a plan isn't in the map then it wasn't | |
# copied over due to an error and we should skip its add-ons. | |
destination_plan_id = plan_map[source_add_on.plan_id] | |
next unless destination_plan_id | |
attributes = source_add_on.attributes.slice(*ADD_ON_ATTRIBUTES).compact | |
attributes[:currencies] = source_add_on.currencies.map(&:attributes) | |
begin | |
destination_add_on = destination_client.create_plan_add_on( | |
plan_id: destination_plan_id, | |
body: attributes | |
) | |
puts "Created add-on '#{destination_add_on.code}'" | |
rescue Recurly::Errors::ValidationError => ex | |
if ex.recurly_error.params.any? { |p| p['param'] == 'code' && p['message'] == 'has already been taken' } | |
destination_add_on = destination_client.update_plan_add_on( | |
plan_id: destination_plan_id, | |
add_on_id: "code-#{source_add_on.code}", | |
body: attributes | |
) | |
puts "Updated add-on '#{destination_add_on.code}'" | |
else | |
puts "Error creating add-on: #{ex}" | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment