Skip to content

Instantly share code, notes, and snippets.

@sanchojaf
Last active March 9, 2018 14:18
Show Gist options
  • Save sanchojaf/29d197027351b3c2e8e3be256ed9fde2 to your computer and use it in GitHub Desktop.
Save sanchojaf/29d197027351b3c2e8e3be256ed9fde2 to your computer and use it in GitHub Desktop.

Conceptos:

RecurringApplicationCharge:

Puede cargar a los clientes por sus aplicaciones en un ciclo de facturación recurrente creando y emitiendo un cargo recurrente por la aplicación. El cargo recurrente de la aplicación se aplica cada 30 días a partir del día en que el comerciante acepta el cargo. Esto significa que una tienda tendrá su propio ciclo de facturación de 30 días con Shopify, más un ciclo independiente de 30 días por cada cargo recurrente de la aplicación.

Después de activar y aprobar un cargo recurrente de la aplicación, el sistema debe manejar el caso en el que se rechazan los pagos futuros. Si una tienda deja de pagar sus facturas, Shopify congelará la cuenta. Esto significa que su cargo recurrente de la aplicación también se congelará y no recibirá ningún pago. En el caso de que una tienda inicie nuevamente los pagos, la tienda se descongelará y los cargos se reanudarán.

Usage charges:

Los cargos basados ​​en el uso permiten que su aplicación cobre una tarifa mensual variable. Su aplicación puede cobrar tarifas en función de una serie de acciones o condiciones, como la cantidad de productos enviados por mes o la cantidad de pedidos procesados ​​por su aplicación.

Como funciona.?

  • Hay que crear un RecurringApplicationCharge por cada cliente.

  • tendra un precio base, por el momento vamos a asumir $10 USD.

  • en la creacion se debe incluir el capped_amount que es la cantidad maxima que se le puede crear al cliente.

  • vamos a asumir un capped_amount de 100 USD.

  • en 'terms' debe aparecer lo que vamos a cobrar por cada orden.

  • vamos a asumir terms un "$1 for 2 orders".

  • Cada vez que sean procesada 10 ordenes, hay que generar un UsageCharge.

  • Digamos que un cliente proceso: 1er mes 50 ordenes, 2do mes 175 ordenses, 3er mes 230 ordenes, 4to mes 310 ordenes

  • en este caso en el 3er proceso 230 ordenes pero como el 'capped_amount' es 100 USD y terms es "$1 for 2 orders", solo se le puede cobrar por 180 ordenes ese mes, ya que seria 10 usd de plan basico y 90 por el plan variable.

  • cuando pase lo anterior, generar automaticamente un cambio del capped_amount, al doble, para ese cliente, en este caso pasaria de 100 USD a 200 USD.

  • Este cambio del capped_amount es equivalente a un cambio de plan.

  • con el cambio anterior se deben cobrar sin problemas las 310 ordenes del 4to mes.

TODOS

1- crear DataType RecurringApplicationCharge

  • activated_on:datetime
  • billing_on:datetime
  • cancelled_on:datetime
  • capped_amount:decimal
  • confirmation_url:string
  • created_at:datetime
  • id:integer
  • name:string
  • price:decimal
  • return_url:string
  • status:string Enumerator (pending|accepted|active|declined|expired|frozen|cancelled)
  • terms:string
  • test:booleean
  • trial_days:integer
  • trial_ends_on:datetime
  • updated_at:datetime

2- Crear flujos para los siguientes endpoints de RecurringApplicationCharge

POST /admin/recurring_application_charges.json Create a recurring application charge

GET /admin/recurring_application_charges/#{id}.json Receive a single RecurringApplicationCharge

GET /admin/recurring_application_charges.json Retrieve all recurring application charges

POST /admin/recurring_application_charges/#{id}/activate.json Activate a recurring application charge

DELETE /admin/recurring_application_charges/#{id}.json Cancel a recurring application charge

PUT /admin/recurring_application_charges/#{id}/customize.json?recurring_application_charge[capped_amount]=200 Customize a recurring application charge

3- crear DataType UsageCharge

  • created_at:datetime
  • description:text
  • id:integer
  • name:string
  • price:decimal
  • recurring_application_charge_id:integer (references)
  • updated_at:datetime

nota: el campo recurring_application_charge_id es una referencia a RecurringApplicationCharge

4- Crear flujos para los siguientes endpoints de UsageCharge

POST /admin/recurring_application_charges/#{id}/usage_charges.json Create a usage charge

GET /admin/recurring_application_charges/#{id}/usage_charges/#{id}.json Receive a single UsageCharge

GET /admin/recurring_application_charges/#{id}/usage_charges.json Retrieve all usage charges

Casos de pruebas.

Estos casos de pruebas de la gema Shopify API, ayudan a tener una idea de las accesiones que se pueden hacer con el api.

require 'test_helper'

class RecurringApplicationChargeTest < Test::Unit::TestCase

  def test_recurring_application_charges_create
    fake "recurring_application_charges", method: :post, status: 201, body: load_fixture('recurring_application_charge')

    charge = ShopifyAPI::RecurringApplicationCharge.create(
      name: "Default Plan",
      price: 10.0,
      return_url: "http://test.com/confirm"
    )

    assert_equal 'http://apple.myshopify.com/admin/charges/654381177/confirm_recurring_application_charge?signature=BAhpBHkQASc%3D--419fc7424f8c290ac2b21b9004ed223e35b52164', charge.confirmation_url
  end

  def test_get_recurring_application_charges
    fake "recurring_application_charges/654381177", method: :get, status: 201, body: load_fixture('recurring_application_charge')

    charge = ShopifyAPI::RecurringApplicationCharge.find(654381177)

    assert_equal "Super Duper Plan", charge.name
  end

  def test_list_recurring_application_charges
    fake "recurring_application_charges", method: :get, status: 201, body: load_fixture('recurring_application_charges')

    charge = ShopifyAPI::RecurringApplicationCharge.find(:all)

    assert_equal "Super Mega Plan", charge.last.name
  end

  def test_list_since_recurring_application_charges
    fake "recurring_application_charges.json?since_id=64512345",extension: false, method: :get, status: 201, body: load_fixture('recurring_application_charges')

    charge = ShopifyAPI::RecurringApplicationCharge.find(:all, params: { since_id: '64512345' })

    assert_equal "Super Mega Plan", charge.last.name
  end

  def test_list_fields_recurring_application_charges
    fake "recurring_application_charges.json?fields=name",extension: false, method: :get, status: 201, body: load_fixture('recurring_application_charges')

    charge = ShopifyAPI::RecurringApplicationCharge.find(:all, params: { fields: 'name' })

    assert_equal "Super Mega Plan", charge.last.name
  end

  def test_pending_recurring_application_charge
    fake "recurring_application_charges", method: :get, status: 201, body: load_fixture('recurring_application_charges')

    charge = ShopifyAPI::RecurringApplicationCharge.pending

    assert_equal "Super Mega Plan2", charge.last.name
  end

  def test_cancelled_recurring_application_charge
    fake "recurring_application_charges", method: :get, status: 201, body: load_fixture('recurring_application_charges')

    charge = ShopifyAPI::RecurringApplicationCharge.cancelled

    assert_equal "Super Mega Plan3", charge.last.name
  end

  def test_accepted_recurring_application_charge
    fake "recurring_application_charges", method: :get, status: 201, body: load_fixture('recurring_application_charges')

    charge = ShopifyAPI::RecurringApplicationCharge.accepted

    assert_equal "Super Mega Plan4", charge.first.name
    assert_equal "Super Mega Plan", charge.last.name
  end

  def test_declined_recurring_application_charge
    fake "recurring_application_charges", method: :get, status: 201, body: load_fixture('recurring_application_charges')

    charge = ShopifyAPI::RecurringApplicationCharge.declined

    assert_equal "Super Mega Plan5", charge.last.name
  end

  def test_activate_recurring_application_charge
    fake "recurring_application_charges", method: :get, status: 201, body: load_fixture('recurring_application_charges')
    fake "recurring_application_charges/455696199/activate", method: :post, status: 200, body: "{}"

    charge = ShopifyAPI::RecurringApplicationCharge.accepted

    assert charge.last.activate
  end

  def test_adjust_recurring_application_charge
    fake "recurring_application_charges/654381177", method: :get, status: 201, body: load_fixture('recurring_application_charge')
    fake "recurring_application_charges/654381177/customize.json?recurring_application_charge%5Bcapped_amount%5D=200", method: :put, body: load_fixture('recurring_application_charge_adjustment'), extension: false

    charge = ShopifyAPI::RecurringApplicationCharge.find(654381177)

    assert charge.customize(capped_amount: 200)
  end

  def test_cancel_recurring_application_charge
    fake "recurring_application_charges", method: :get, status: 201, body: load_fixture('recurring_application_charges')
    fake "recurring_application_charges/455696194", method: :delete, status: 200, body: "{}"

    charge = ShopifyAPI::RecurringApplicationCharge.current
    assert charge.cancel
  end

  def test_usage_charges_recurring_application_charge_found
    fake "recurring_application_charges/654381177", method: :get, status: 201, body: load_fixture('recurring_application_charge')
    fake "recurring_application_charges/654381177/usage_charges", method: :get, status: 201, body: load_fixture('usage_charges')

    charge = ShopifyAPI::RecurringApplicationCharge.find(654381177)
    usage_charges = charge.usage_charges

    assert_equal 2, usage_charges.length
  end

  def test_usage_charges_recurring_application_charge_not_found
    fake "recurring_application_charges/654381177", method: :get, status: 201, body: load_fixture('recurring_application_charge')
    fake "recurring_application_charges/654381177/usage_charges", method: :get, status: 201, body: "[]"

    charge = ShopifyAPI::RecurringApplicationCharge.find(654381177)
    usage_charges = charge.usage_charges

    assert_equal 0, usage_charges.length
  end

  def test_no_recurring_application_charge_found
    fake "recurring_application_charges", body: {recurring_application_charges: []}.to_json

    assert_equal 0, ShopifyAPI::RecurringApplicationCharge.all.count
    assert_equal nil, ShopifyAPI::RecurringApplicationCharge.current
    assert_equal [], ShopifyAPI::RecurringApplicationCharge.pending
  end

  def test_recurring_application_charge_not_found_error
    fake "recurring_application_charges", body: '{"errors":"Not Found"}', status: 404

    all_application_charges = ShopifyAPI::RecurringApplicationCharge.all
    if ActiveResource::VERSION::MAJOR >= 5 || (ActiveResource::VERSION::MAJOR == 4 && ActiveResource::VERSION::MINOR >= 2)
      assert_equal [], all_application_charges
    else
      assert_equal nil, all_application_charges
    end

    assert_equal nil, ShopifyAPI::RecurringApplicationCharge.current
    assert_equal [],  ShopifyAPI::RecurringApplicationCharge.pending
  end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment