Packages
shopifex
0.3.6
2.4.0
2.3.0
2.2.2
2.2.1
2.2.0
2.1.20
2.1.19
2.1.18
2.1.17
2.1.16
2.1.15
2.1.14
2.1.13
2.1.12
2.1.11
2.1.10
2.1.9
2.1.8
2.1.7
2.1.6
2.1.5
2.1.4
2.1.3
2.1.2
2.1.1
2.1.0
2.0.1
2.0.0
1.1.1
1.1.0
1.0.1
1.0.0
0.6.2
0.6.1
0.6.0
0.5.7
0.5.6
0.5.5
0.5.4
0.5.3
0.5.2
0.5.1
0.5.0
0.4.1
0.4.0
0.3.6
0.3.5
0.3.4
0.3.3
0.3.2
0.3.1
0.3.0
0.2.1
0.2.0
0.1.5
0.1.4
0.1.3
0.1.2
0.1.1
0.1.0
Phoenix boilerplate for Shopify Embedded App SDK
Current section
Files
Jump to
Current section
Files
lib/shopifex_web/controllers/payment_controller.ex
defmodule ShopifexWeb.PaymentController do
@moduledoc """
You can use this module inside of another controller to handle initial iFrame load and shop installation
Example:
mix phx.gen.html Shops Plan plans name:string price:string features:array grants:array test:boolean
mix phx.gen.html Shops Grant grants shop:references:shops charge_id:integer grants:array
```elixir
defmodule MyAppWeb.PaymentController do
use MyAppWeb, :controller
use ShopifexWeb.PaymentController
# Thats it! You can now configure your purchasable products :)
end
```
"""
@doc """
An optional callback called after a payment is completed. By default, this function
redirects the user to the app index within their Shopify admin panel.
## Example
def after_payment(conn, shop, plan, grant) do
# send yourself an e-mail about payment
# follow default behaviour.
super(conn, shop, plan, grant)
end
"""
@callback after_payment(
Plug.Conn.t(),
Ecto.Schema.t(),
Ecto.Schema.t(),
Ecto.Schema.t()
) ::
Plug.Conn.t()
@optional_callbacks after_payment: 4
defmacro __using__(_opts) do
quote do
@behaviour ShopifexWeb.PaymentController
require Logger
@doc """
Displays a list of available plans with which the user can access
the guarded feature
"""
def show_plans(conn, %{"guard" => guard, "redirect_after" => redirect_after}) do
plans = Shopifex.Shops.list_plans_granting_guard(guard)
conn
|> put_view(ShopifexWeb.PaymentView)
|> put_layout({ShopifexWeb.LayoutView, "app.html"})
|> render("show-plans.html",
plans: plans,
guard: guard,
redirect_after: redirect_after,
shop_url: conn.private.shop_url
)
end
def select_plan(conn, %{"plan_id" => plan_id, "redirect_after" => redirect_after}) do
plan = Shopifex.Shops.get_plan!(plan_id)
shop = conn.private.shop
{:ok, charge} = create_charge(shop, plan)
Shopifex.RedirectAfterAgent.set(charge["id"], redirect_after)
send_resp(conn, 200, Jason.encode!(charge))
end
defp create_charge(shop, plan = %{type: "recurring_application_charge"}) do
redirect_uri = Application.get_env(:shopifex, :payment_redirect_uri)
body =
Jason.encode!(%{
recurring_application_charge: %{
name: plan.name,
price: plan.price,
test: plan.test,
return_url: "#{redirect_uri}?plan_id=#{plan.id}"
}
})
case HTTPoison.post(
"https://#{shop.url}/admin/api/2021-01/recurring_application_charges.json",
body,
"X-Shopify-Access-Token": shop.access_token,
"Content-Type": "application/json"
) do
{:ok, resp} ->
{:ok, Jason.decode!(resp.body)["recurring_application_charge"]}
end
end
defp create_charge(shop, plan = %{type: "application_charge"}) do
redirect_uri = Application.get_env(:shopifex, :payment_redirect_uri)
body =
Jason.encode!(%{
application_charge: %{
name: plan.name,
price: plan.price,
test: plan.test,
return_url: "#{redirect_uri}?plan_id=#{plan.id}"
}
})
case HTTPoison.post(
"https://#{shop.url}/admin/api/2021-01/application_charges.json",
body,
"X-Shopify-Access-Token": shop.access_token,
"Content-Type": "application/json"
) do
{:ok, resp} ->
{:ok, Jason.decode!(resp.body)["application_charge"]}
end
end
def complete_payment(conn, %{
"charge_id" => charge_id,
"plan_id" => plan_id
}) do
plan = Shopifex.Shops.get_plan!(plan_id)
shop = conn.private.shop
{:ok, grant} =
Shopifex.Shops.create_grant(%{
shop: shop,
charge_id: charge_id,
grants: plan.grants,
remaining_usages: plan.usages
})
after_payment(conn, shop, plan, grant)
end
@impl ShopifexWeb.PaymentController
def after_payment(conn, shop, plan, grant) do
redirect_after = Shopifex.RedirectAfterAgent.get(grant.charge_id)
api_key = Application.get_env(:shopifex, :api_key)
redirect(conn, external: "https://#{shop.url}/admin/apps/#{api_key}#{redirect_after}")
end
defoverridable after_payment: 4
end
end
end