Skip to content

Commit

Permalink
No-hosted Paypal button, removed Stripe and websockets for validation
Browse files Browse the repository at this point in the history
  • Loading branch information
aguxez committed Feb 28, 2018
1 parent 465e774 commit 42d5ca7
Show file tree
Hide file tree
Showing 27 changed files with 197 additions and 196 deletions.
2 changes: 0 additions & 2 deletions apps/ecom/config/config.exs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ use Mix.Config
config :arc,
storage: Arc.Storage.Local

config :ecom, env: Mix.env()

# General application configuration
config :ecom,
namespace: Ecom,
Expand Down
2 changes: 2 additions & 0 deletions apps/ecom/config/dev.exs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use Mix.Config

config :ecom, env: :dev

import_config "dev.secret.exs"
2 changes: 2 additions & 0 deletions apps/ecom/config/test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ config :argon2_elixir,
t_cost: 2,
m_cost: 12

config :ecom, env: :test

# Configure your database
config :ecom, Ecom.Repo,
adapter: Ecto.Adapters.Postgres,
Expand Down
3 changes: 2 additions & 1 deletion apps/ecom/lib/cart_task.ex
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ defmodule Ecom.CartTask do
def db_update_cart_values(conn, user, products_to_update) do
updated_values =
Enum.reduce(products_to_update, user.cart.products, fn({k, v}, acc) ->
put_in(acc, [k, "value"], v)
value = String.to_integer(v)
put_in(acc, [k, "value"], value)
end)

case Accounts.update_cart(user.cart, %{products: updated_values}) do
Expand Down
1 change: 1 addition & 0 deletions apps/ecom/lib/interfaces/accounts.ex
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ defmodule Ecom.Interfaces.Accounts do
defdelegate create_cart(params), to: Accounts
defdelegate create_user(params), to: Accounts
defdelegate get_product!(id), to: Accounts
defdelegate get_user!(id), to: Accounts
defdelegate update_product(product, product_params), to: Accounts
defdelegate delete_product(id), to: Accounts
end
10 changes: 0 additions & 10 deletions apps/ecom/lib/interfaces/checker.ex

This file was deleted.

11 changes: 11 additions & 0 deletions apps/ecom/lib/interfaces/worker.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
defmodule Ecom.Interfaces.Worker do
@moduledoc false

alias Ecom.Worker

defdelegate update_user(user, params_password, attrs), to: Worker
defdelegate can_create_product?(user, params), to: Worker
defdelegate sign_in(user, password), to: Worker
defdelegate new_user(params), to: Worker
defdelegate empty_user_cart(user, proc_id, param_proc_id), to: Worker
end
10 changes: 2 additions & 8 deletions apps/ecom/lib/payments/processor.ex
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,7 @@ defmodule Ecom.Payments.Processor do
end

# Real Payment
defp make_payment(%{token: token, total: total}, :stripe) do
payment = Gringotts.purchase(Stripe, total, %{}, source: token)

cond do
payment["status"] == "succeeded" -> {:ok, :accepted}
payment["status"] == "failed" -> {:error, {:failed, payment}}
payment["error"] -> {:error, {:req_error, payment}}
end
defp make_payment(_params, :paypal) do
:ok
end
end
13 changes: 12 additions & 1 deletion apps/ecom/lib/checker.ex → apps/ecom/lib/worker.ex
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
defmodule Ecom.Checker do
defmodule Ecom.Worker do
@moduledoc false

alias Comeonin.Argon2
Expand Down Expand Up @@ -47,4 +47,15 @@ defmodule Ecom.Checker do
{:error, changeset} -> {:error, changeset}
end
end

def empty_user_cart(user, sess_proc_id, param_proc_id) do
with true <- sess_proc_id == param_proc_id,
{:ok, %Cart{}} <- Accounts.update_cart(user.cart, %{products: %{}}) do

{:ok, :empty}
else
false -> {:error, :invalid_proc_id}
{:error, _changeset} -> {:error, :unable_to_empty}
end
end
end
1 change: 0 additions & 1 deletion apps/ecom/mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ defmodule Ecom.Mixfile do
{:arc_ecto, "~> 0.7.0"},
{:argon2_elixir, "~> 1.2"},
{:guardian, "~> 1.0"},
{:gringotts, "~> 1.0"},
{:ex_money, "~> 1.1.0"},
{:comeonin, "~> 4.1"},
{:bodyguard, "~> 2.2"},
Expand Down
61 changes: 1 addition & 60 deletions apps/ecom_web/assets/js/app.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import "phoenix_html";
import "./socket";
// Way to import 'Foundation'
import "foundation-sites/dist/js/foundation";

Expand All @@ -13,63 +14,3 @@ var editor = new SimpleMDE({
autoDownloadFontAwesome: false,
})

// Stripe form
var stripe = Stripe('pk_test_gytJ3osyEvhIHnKC0PP7dj8C');
var elements = stripe.elements();

var style = {
base: {
// Add your base input styles here. For example:
fontSize: '16px',
color: "#32325d",
}
};

// Create an instance of the card Element.
var card = elements.create('card', {style: style});

// Add an instance of the card Element into the `card-element` <div>.
card.mount('#card-element');

// Listening for errors
card.addEventListener('change', function(event) {
var displayError = document.getElementById('card-errors');
if (event.error) {
displayError.textContent = event.error.message;
} else {
displayError.textContent = '';
}
});

// Form intercept
// Create a token or display an error when the form is submitted.
var form = document.getElementById('payment-form');

form.addEventListener('submit', function(event) {
event.preventDefault();

stripe.createToken(card).then(function(result) {
if (result.error) {
// Inform the customer that there was an error.
var errorElement = document.getElementById('card-errors');
errorElement.textContent = result.error.message;
} else {
// Send the token to your server.
stripeTokenHandler(result.token);
}
});
});

function stripeTokenHandler(token) {
// Insert the token ID into the form so it gets submitted to the server
var form = document.getElementById('payment-form');
var hiddenInput = document.createElement('input');
hiddenInput.setAttribute('type', 'hidden');
hiddenInput.setAttribute('name', 'stripeToken');
hiddenInput.setAttribute('value', token.id);
form.appendChild(hiddenInput);

// Submit the form
form.submit();
}

80 changes: 29 additions & 51 deletions apps/ecom_web/assets/js/socket.js
Original file line number Diff line number Diff line change
@@ -1,62 +1,40 @@
// NOTE: The contents of this file will only be executed if
// you uncomment its entry in "assets/js/app.js".

// To use Phoenix channels, the first step is to import Socket
// and connect at the socket path in "lib/web/endpoint.ex":
import {Socket} from "phoenix"

let socket = new Socket("/socket", {params: {token: window.userToken}})

// When you connect, you'll often need to authenticate the client.
// For example, imagine you have an authentication plug, `MyAuth`,
// which authenticates the session and assigns a `:current_user`.
// If the current user exists you can assign the user's token in
// the connection for use in the layout.
//
// In your "lib/web/router.ex":
//
// pipeline :browser do
// ...
// plug MyAuth
// plug :put_user_token
// end
//
// defp put_user_token(conn, _) do
// if current_user = conn.assigns[:current_user] do
// token = Phoenix.Token.sign(conn, "user socket", current_user.id)
// assign(conn, :user_token, token)
// else
// conn
// end
// end
//
// Now you need to pass this token to JavaScript. You can do so
// inside a script tag in "lib/web/templates/layout/app.html.eex":
//
// <script>window.userToken = "<%= assigns[:user_token] %>";</script>
//
// You will need to verify the user token in the "connect/2" function
// in "lib/web/channels/user_socket.ex":
//
// def connect(%{"token" => token}, socket) do
// # max_age: 1209600 is equivalent to two weeks in seconds
// case Phoenix.Token.verify(socket, "user socket", token, max_age: 1209600) do
// {:ok, user_id} ->
// {:ok, assign(socket, :user, user_id)}
// {:error, reason} ->
// :error
// end
// end
//
// Finally, pass the token on connect as below. Or remove it
// from connect if you don't care about authentication.
let token = document.querySelector("meta[name=channel_token]").getAttribute("content");
let socket = new Socket("/socket", {params: {token: token}})

socket.connect()

// Now that you are connected, you can join channels with a topic:
let channel = socket.channel("topic:subtopic", {})
let channel = socket.channel("payments:*", {})
channel.join()
.receive("ok", resp => { console.log("Joined successfully", resp) })
.receive("error", resp => { console.log("Unable to join", resp) })

let form = document.getElementById("paypal-form");

if (window.location.pathname == "/payments") {
form.addEventListener("submit", event => {
event.preventDefault();
let ser = $("#paypal-form").serializeArray();

channel.push("form_submit", {form: ser});
})
}

channel.on("form_resubmit", event => {
let hid_in = document.createElement("input");

$("input[name='amount']").remove();


hid_in.setAttribute("type", "hidden");
hid_in.setAttribute("name", "amount");
hid_in.setAttribute("value", event.form.amount.value);

form.appendChild(hid_in);

form.submit();
})

export default socket
26 changes: 26 additions & 0 deletions apps/ecom_web/lib/ecom_web/channels/payments_channel.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
defmodule EcomWeb.PaymentsChannel do
@moduledoc false

use Phoenix.Channel

def join("payments:" <> _sub_topic, _, socket) do
{:ok, socket}
end

def handle_in("form_submit", %{"form" => _data}, socket) do
total = get_product_total(socket.assigns)
attr = %{"amount" => %{"value" => total}}

broadcast!(socket, "form_resubmit", %{form: attr})

{:noreply, socket}
end

defp get_product_total(%{user: user}) do
products = Map.values(user.cart.products)

products
|> Enum.map(fn product -> product["price"] * product["value"] end)
|> Enum.sum()
end
end
17 changes: 14 additions & 3 deletions apps/ecom_web/lib/ecom_web/channels/user_socket.ex
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
defmodule EcomWeb.UserSocket do
@moduledoc false

use Phoenix.Socket

alias Ecom.Interfaces.Accounts

## Channels
# channel "room:*", EcomWeb.RoomChannel
channel "payments:*", EcomWeb.PaymentsChannel

## Transports
transport :websocket, Phoenix.Transports.WebSocket
Expand All @@ -19,8 +23,15 @@ defmodule EcomWeb.UserSocket do
#
# See `Phoenix.Token` documentation for examples in
# performing token verification on connect.
def connect(_params, socket) do
{:ok, socket}
def connect(%{"token" => token}, socket) do
# Max age of 2 weeks
case Phoenix.Token.verify(socket, "user", token, max_age: 1209600) do
{:ok, user_id} ->
socket = assign(socket, :user, Accounts.get_user!(user_id))
{:ok, socket}
{:error, _} ->
:error
end
end

# Socket id's are topics that allow you to identify all sockets for a given user:
Expand Down
4 changes: 2 additions & 2 deletions apps/ecom_web/lib/ecom_web/controllers/account_controller.ex
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ defmodule EcomWeb.AccountController do

use EcomWeb, :controller

alias Ecom.Interfaces.Checker
alias Ecom.Interfaces.Worker
alias Ecom.Interfaces.Accounts

plug :scrub_params, "user" when action in [:update]
Expand All @@ -19,7 +19,7 @@ defmodule EcomWeb.AccountController do
user = current_user(conn)
attrs = %{password: user_params["new_password"], password_confirmation: user_params["new_password_confirmation"]}

case Checker.update_user(user, user_params["password"], attrs) do
case Worker.update_user(user, user_params["password"], attrs) do
{:ok, :accept} ->
conn
|> put_flash(:success, gettext("Account updated successfully"))
Expand Down
4 changes: 2 additions & 2 deletions apps/ecom_web/lib/ecom_web/controllers/admin_controller.ex
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ defmodule EcomWeb.AdminController do

import Ecto.Query, only: [from: 2]

alias Ecom.Interfaces.{Checker, Accounts}
alias Ecom.Interfaces.{Worker, Accounts}
alias Ecom.Repo
alias Ecom.Uploaders.Image

Expand Down Expand Up @@ -43,7 +43,7 @@ defmodule EcomWeb.AdminController do
user = current_user(conn)
params = Map.merge(product_params, %{"user_id" => user.id})

case Checker.can_create_product?(user, params) do
case Worker.can_create_product?(user, params) do
{:ok, product} ->
conn
|> put_flash(:success, gettext("Product created successfully"))
Expand Down
4 changes: 3 additions & 1 deletion apps/ecom_web/lib/ecom_web/controllers/cart_controller.ex
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,9 @@ defmodule EcomWeb.CartController do
updated_values =
Enum.reduce(products_to_update, user_cart, fn({k, v}, acc) ->
id = String.to_integer(k)
put_in(acc, [id, "value"], v)
value = String.to_integer(v)
# Make value an a String
put_in(acc, [id, "value"], value)
end)

{:ok, put_session(conn, :user_cart, updated_values)}
Expand Down
Loading

0 comments on commit 42d5ca7

Please sign in to comment.