
Introdução
Integrar a sua aplicação com um meio de pagamento pode ser uma tarefa difícil e frustrante, porém na maior parte dos APPs com fins lucrativos é necessário ter uma maneira de receber dinheiro do usuário pelo sistema.
Neste Post eu falo sobre a integração do Rails com o checkout transparente do PagSeguro (Pagamento todo feito na nossa plataforma, sem redirecionar para o PagSeguro), vamos percorrer todo o caminho, passando pela criação do HTML, JS, dos Controllers e models, deploy para o Heroku e por fim o teste na plataforma do PagSeguro.
Vamos lá \o/
O que vamos aprender
- Como criar a estrutura para pegar os dados de pagamento do usuário
- Como enviar a solicitação de Pagamento para o PagSeguro
- Como Subir nossa aplicação para o Heroku
- Como receber as notificações do PagSeguro
- Como testar tudo isto 🙂
Ingredientes
- Ruby 2.3.1
- Rails 5
- Devise (Gem)
- bootstrap-sass (Gem)
- pagseguro-oficial (Gem)
- Heroku
Objetivos
Vamos começar criando a plataforma para criar novos produtos para que o usuário possa escolher um e ir para a tela de pagamento onde ele vai colocar seus dados de pagamentos e nós vamos via javascript chamar o PagSeguro para pegar as Opções de pagamento (Parcelamento), depois vamos subir nosso APP no heroku para ter uma URL válida para que o PagSeguro possa nos enviar notificações com o status do pagamento e por fim vamos listar todos os pedidos de pagamento do sistema e verificar se o status realmente mudou baseado nas chamadas do PagSeguro.
Passo a Passo
-
Criação da conta no PagSeguro
-
Criação da estrutura do Projeto
-
Inclusão do Javascript
- Recebendo notificações
- Subindo para o Heroku
-
Testando tudo isto 🙂
Mãos à Obra \o/
Parte 1 – Criação da conta no PagSeguro
- Caso você ainda não possua uma conta no PagSeguro acesse esse link (https://pagseguro.uol.com.br/registration/registration.jhtml?tipo=cadastro#!vendedor) e crie uma conta.
- O PagSeguro vai enviar um email de confirmação, basta ir até sua caixa de email e confirmar 🙂
- Agora acesse seu Painel de sandbox (clicando nesse link) e clique em vendedor no menu lateral, guarde seu token para usarmos no projeto para autenticar nossa aplicação no PagSeguro.
- Pronto \o/
Parte 2 – Criação da estrutura do Projeto
-
- Crie o Projeto (Vamos usar o database como PostgreSQL para subirmos nosso APP no heroku)
1rails new pagseguro --database=postgresql - Inclua as Gems que vamos usar no seu Gemfile:
123gem 'bootstrap-sass'gem "pagseguro-oficial", "~> 2.5.0"gem "devise" - Instale as Gems rodando:
1bundle - Configure seu arquivo ‘config/database.yml’ com as credenciais para acessar o seu banco postgreSQL instalado na sua máquina. (Caso você não saiba como instalar o postgreSQL, veja aqui https://www.digitalocean.com/community/tutorials/how-to-setup-ruby-on-rails-with-postgres)
- Gere seus scaffolds para poder incluir novos produtos e usuários:
12rails g scaffold product title:string price:decimal description:textrails g scaffold user name:string - Agora crie o model e o controller order para podermos armazenar as transações do nosso sistema:
12rails g model order product_id:integer price:integer status:string buyer_name:string reference:stringrails g controller order new create index - Agora vamos até o model Order e vamos colocar a associação com o Produto, em “/app/models/order.rb” acrescente a seguinte linha:
1belongs_to :product - No Model Product vamos colocar a associação com o Model Order, em “/app/models/product.rb” coloque a seguinte linha:
1has_many :orders - Agora vamos gerar nosso Controller Home onde vai ficar a nossa lista de Produtos que o usuário pode comprar:
1rails g controller home index - No Arquivo “/app/controller/home_controller.rb” substitua o conteúdo por:
123456class HomeController < ApplicationController skip_before_filter :authenticate_user!, :only => :indexdef index@products = Product.allendend - Agora para preparamos nossa View Home Index para mostrar a lista de Produtos e o botão de compra substitua o conteúdo do aqui ‘/app/views/home/index.html.erb’ por:
12345678910<h4>Nossos Produtos:</h4><hr /><br /><% @products.each do |product| %><p>Nome: <%= product.title %></p><p>Preço: R$<%= product.price %></p><p>Descrição: <%= product.description %></p><td><%= link_to 'Comprar Produto', order_new_path(product_id: product.id), class: 'btn btn-success' %></td><hr /><% end %> - No nosso arquivo ‘config/routes.rb’, substitua a linha ‘get ‘home/index’ por:
1root to: 'home#index' - E ainda no routes.rb substitua a linha “get ‘order/create’ por:”
1post 'order/create' - Instale o devise, rodando:
1rails generate devise:install - Agora para incluir o devise no nosso user, rode:
1rails generate devise User - Crie o banco de dados e rode as migrations:
1rake db:create && rake db:migrate - Agora coloque a seguinte linha no arquivo ‘app/controllers/application_controller.rb’ após a linha ‘class ApplicationController < ActionController::Base' e antes da linha 'end':
1before_action :authenticate_user!
- Agora inclua o bootstrap no seu projeto, no arquivo ‘app/assets/javascripts/application.js’ substitua o conteúdo por:
1234//= require jquery//= require jquery_ujs//= require bootstrap-sprockets//= require_tree . - Renomeie seu arquivo ‘app/assets/stylesheets/application.css’ para ‘app/assets/stylesheets/application.scss’
- Agora substitua o conteúdo deste arquivo por:
12@import "bootstrap-sprockets";@import "bootstrap"; - Vamos criar nosso Form de pagamento, substitua o conteúdo da sua view ‘app/views/order/new.html.erb’ por:
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154<div class="container"><div class="row"><h2 class="col-md-4 col-md-offset-4">Finalize sua compra</h2></div><legend>Dados do Produto</legend><p>Nome: <%= @product.title %></p><p>Preço: $<%= @product.price %></p><p>Descrição: <%= @product.description %></p><input id='price' type="hidden" value="210"><div id="payment_datas"><form class="form-horizontal" role="form" action="/order/create" method="POST"><div id='payment-datas'><div><input type="hidden" name="product_id" value="<%= @product.id %>"><input type="hidden" name="card_token" id="card_token" /><input type="hidden" name="sender_hash" id="sender_hash" /><input type="hidden" name="session_id" id="session_id" value="<%= @session_id %>" /><%= csrf_meta_tag %></div><fieldset><legend>Dados Pessoais do Comprador</legend><div class="form-group"><label class="col-sm-3 control-label">Nome</label><div class="col-sm-4"><input type="text" class="form-control" name='name' placeholder="exp: José Paulo" required></div></div><div class="form-group"><label class="col-sm-3 control-label">Email</label><div class="col-sm-4"><input type="text" class="form-control" name='email' placeholder="exp: c56048717318@sandbox.pagseguro.com.br" required></div>*No sandbox use o email: c56048717318@sandbox.pagseguro.com.br</div><div class="form-group"><label class="col-sm-3 control-label">Cpf</label><div class="col-sm-2"><input type="text" class="form-control" name='cpf' placeholder="39813476548" required></div>* Não use . ou - no CPF ou trate isso :)</div><div class="form-group"><label class="col-sm-3 control-label">Telefone</label><div class="col-sm-1"><input type="text" class="form-control" name='phone_code' placeholder="11" required></div><div class="col-sm-2"><input type="text" class="form-control" name='phone_number' placeholder="997874567" required></div></div><div class="form-group"><label class="col-sm-3 control-label">Data de Nascimento</label><div class="col-sm-2"><input type="text" class="form-control" name='birthday' placeholder="10/10/1991" required></div></div></fieldset><fieldset><legend>Dados do Cartão</legend><div class="form-group"><label class="col-sm-3 control-label">Name on Card</label><div class="col-sm-4"><input type="text" class="form-control" name='card_name' id='card-name' placeholder="Card Holder's Name" required></div></div><div class="form-group"><label class="col-sm-3 control-label" for="card-number">Card Number</label><div class="col-sm-4"><input type="text" class="form-control" name='card-number' id='card-number' placeholder="Debit/Credit Card Number" required></div><div class="col-sm-1"><span id="card-flag"></span></div></div><div class="form-group"><label class="col-sm-3 control-label">Expiration Date</label><div class="col-sm-9"><div class="row"><div class="col-xs-3"><select class="form-control col-sm-2" name='card-month' id='card-month' required><option>Month</option><option value="01">Jan (01)</option><option value="02">Feb (02)</option><option value="03">Mar (03)</option><option value="04">Apr (04)</option><option value="05">May (05)</option><option value="06">June (06)</option><option value="07">July (07)</option><option value="08">Aug (08)</option><option value="09">Sep (09)</option><option value="10">Oct (10)</option><option value="11">Nov (11)</option><option value="12">Dec (12)</option></select></div><div class="col-xs-3"><select class="form-control" name='card-year' id='card-year' required><option value="2016">2016</option><option value="2017">2017</option><option value="2018">2018</option><option value="2019">2019</option><option value="2010">2020</option><option value="2021">2021</option><option value="2022">2022</option><option value="2023">2023</option><option value="2024">2024</option><option value="2025">2025</option><option value="2026">2026</option><option value="2027">2027</option><option value="2028">2028</option><option value="2029">2029</option><option value="2030">2030</option></select></div></div></div></div><div class="form-group" id="card-cvv-box" style="display: none"><label class="col-sm-3 control-label">Card CVV</label><div class="col-sm-3"><input type="text" class="form-control" name='card-cvv' id='card-cvv' placeholder="Security Code"></div></div><div class="form-group" id="card-options-box" style="display: none"><hr /><label class="col-sm-3 control-label">Payment Options (parcelamentos)</label><div class="col-sm-3"><select class="form-control col-sm-2" id="card-options"></select></div><hr /></div><div class="form-group"><div class="col-sm-offset-3 col-sm-9"><button type="button" class="btn btn-success" id="buy-button">Confirmar dados do cartão</button></div></div></fieldset></div><div id='finish-buy' style="display: none"><fieldset><legend>Confirmar Pagamento</legend><div class="form-group"><div class="col-sm-offset-3 col-sm-9"><%= csrf_meta_tags %><button type="submit" class="btn btn-success" id="buy-button">Finalizar Compra</button><button type="button" class="btn btn-primary" id="edit-payment">Editar Meio de Pagamento</button></div></div></fieldset></div></form></div></div>
- Crie o Projeto (Vamos usar o database como PostgreSQL para subirmos nosso APP no heroku)
- Vamos criar nossa listagem de orders (pedidos de compras), substitua o conteúdo da sua view ‘app/views/order/index.html.erb’ por:
12345678910<h4>Orders list:</h4><br /><% @orders.each do |order| %><p>Product Name: <%= order.product.title %></p><p>User: <%= order.buyer_name %></p><p>Status: <%= order.status %></p><hr /><% end %><a href="/products">Produtos</a>
- Altere seu arquivo ‘/app/views/layout/application.html.erb’ para incluir o javascript do checkout transparente do PagSeguro, seu arquivo deve ficar assim:
12345678910111213<!DOCTYPE html><html><head><title>Pagseguro</title><%= csrf_meta_tags %><%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %><%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %><script type="text/javascript" src="https://stc.sandbox.pagseguro.uol.com.br/pagseguro/api/v2/checkout/pagseguro.directpayment.js"></script></head><body><%= yield %></body></html>
*Lembrando que caso você queira usar em Production o link para o javascript de production do checkout transparente do Pagseguro é: https://stc.pagseguro.uol.com.br/pagseguro/api/v2/checkout/pagseguro.directpayment.js - Agora no seu ‘app/controllers/order_controller.rb’ vamos colocar nosso métodos para criar um novo pagamento e para listar os pagamentos, substitua o conteúdo do seu controller pelo abaixo (Leia os comentários no código para entender o que foi feito):
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071class OrderController < ApplicationControllerprotect_from_forgery# Gerar um Token de sessão para nosso pagamentodef new@product = Product.find(params[:product_id])@session_id = (PagSeguro::Session.create).idend# Enviar nosso pagamento para o Pagsegurodef create@product = Product.find(params[:product_id])payment = PagSeguro::CreditCardTransactionRequest.newpayment.notification_url = "https://secret-wave-53573.herokuapp.com/notification "payment.payment_mode = "gateway"# Aqui vão os itens que serão cobrados na transação, caso você tenha multiplos itens# em um carrinho altere aqui para incluir sua lista de itenspayment.items << { id: @product.id, description: @product.description, amount: @product.price, weight: 0 } # Criando uma referencia para a nossa ORDER reference = "REF_#{(0...8).map { (65 + rand(26)).chr }.join}_#{@product.id}" payment.reference = reference payment.sender = { hash: params[:sender_hash], name: params[:name], email: params[:email] } payment.credit_card_token = params[:card_token] payment.holder = { name: params[:card_name], birth_date: params[:birthday], document: { type: "CPF", value: params[:cpf] }, phone: { area_code: params[:phone_code], number: params[:phone_number] } } payment.installment = { value: @product.price, quantity: 1 } puts "=> REQUEST"puts PagSeguro::TransactionRequest::RequestSerializer.new(payment).to_paramsputspayment.create# Cria uma Order para registro das transaçõesOrder.create(product_id: @product.id, buyer_name: params[:name], reference: reference, status: 'pending')if payment.errors.any?puts "=> ERRORS"puts payment.errors.join("\n")render plain: "Erro No Pagamento #{payment.errors.join("\n")}"elseputs "=> Transaction"puts " code: #{payment.code}"puts " reference: #{payment.reference}"puts " type: #{payment.type_id}"puts " payment link: #{payment.payment_link}"puts " status: #{payment.status}"puts " payment method type: #{payment.payment_method}"puts " created at: #{payment.created_at}"puts " updated at: #{payment.updated_at}"puts " gross amount: #{payment.gross_amount.to_f}"puts " discount amount: #{payment.discount_amount.to_f}"puts " net amount: #{payment.net_amount.to_f}"puts " extra amount: #{payment.extra_amount.to_f}"puts " installment count: #{payment.installment_count}"puts " => Items"puts " items count: #{payment.items.size}"payment.items.each do |item|puts " item id: #{item.id}"puts " description: #{item.description}"puts " quantity: #{item.quantity}"puts " amount: #{item.amount.to_f}"endputs " => Sender"puts " name: #{payment.sender.name}"puts " email: #{payment.sender.email}"puts " phone: (#{payment.sender.phone.area_code}) #{payment.sender.phone.number}"puts " document: #{payment.sender.document}: #{payment.sender.document}"render plain: "Sucesso, seu pagamento será processado :)"endenddef index@orders = Order.allendend - Rode o projeto:
1rails s - Crie um User pelo form do devise para ser o administrador da loja acessando no browser ‘http://localhost:3000/users/sign_up‘:
1<a href="http://165.227.206.32/wp-content/uploads/2017/01/Captura-de-tela-de-2017-01-06-16-27-24-2.png"><img class="aligncenter size-full wp-image-1280" src="http://165.227.206.32/wp-content/uploads/2017/01/Captura-de-tela-de-2017-01-06-16-27-24-2.png" alt="captura-de-tela-de-2017-01-06-16-27-24" width="517" height="533" /></a> - Agora crie um Product acessando no browser ‘http://localhost:3000/products/new‘:
1<a href="http://165.227.206.32/wp-content/uploads/2017/01/Captura-de-tela-de-2017-01-06-16-33-58-2.png"><img class="aligncenter size-full wp-image-1281" src="http://165.227.206.32/wp-content/uploads/2017/01/Captura-de-tela-de-2017-01-06-16-33-58-2.png" alt="captura-de-tela-de-2017-01-06-16-33-58" width="393" height="339" /></a>
- Agora você precisa criar um initializer para configurar seu PagSeguro. Crie um arquivo no seguinte path ‘app/config/initializers/pagseguro.rb’, cole o código abaixo e coloque suas credenciais:
123456PagSeguro.configure do |config|config.token = "SEU_TOKEN_DO_PAGSEGURO"config.email = "SEU_EMAIL"config.environment = :sandbox # ou :sandbox. O padrão é production.config.encoding = "UTF-8"end - Agora rode seu servidor:
1rails s - No browser acesse ‘https://onebitcode.com/celebrities-online-dating/‘ e clique em comprar em algum produto da lista.
1<a href="http://165.227.206.32/wp-content/uploads/2017/01/Captura-de-tela-de-2017-01-06-17-35-48-2.png"><img class="aligncenter size-full wp-image-1283" src="http://165.227.206.32/wp-content/uploads/2017/01/Captura-de-tela-de-2017-01-06-17-35-48-2.png" alt="captura-de-tela-de-2017-01-06-17-35-48" width="663" height="397" /></a> - A estrutura do nosso App está pronta, agora vamos incluir nosso JavaScript.
Parte 3 – Inclusão do JavaScript
-
- Crie um arquivo em ‘/app/assets/javascripts/pagseguro.js’ e cole o seguinte código dentro dele (lembre-se de ler os comentários no código para entender as funções):
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112$( document ).ready(function() {// Inicia o PagSeguroPagSeguroDirectPayment.setSessionId($("#session_id").val());// Verifica se existe um cartão preenchidocard_flag();// Pega o Sender Hash e o Card Token quando o usuário confirma os dados do cartão$("#buy-button").click(function() {$('#sender_hash').val(PagSeguroDirectPayment.getSenderHash());var params = {cardNumber: $("#card-number").val(),cvv: $("#card-cvv").val(),expirationMonth: $("#card-month").val(),expirationYear: $("#card-year").val(),success: function (response) {//token gerado, esse deve ser usado na chamada da API do Checkout Transparente$('#card_token').val(response['card']['token']);$('#payment-datas').hide();$('#finish-buy').fadeIn();},error: function (response) {alert('As informações sobre o cartão estão incorretas')}}PagSeguroDirectPayment.createCardToken(params);});// Muda do step de finalização para o step de edição do meio de pagamento$("#edit-payment").click(function() {$('#finish-buy').hide();$('#payment-datas').fadeIn();});// Verifica informações sobre o cartão digitado como a bandeira//, tamanho do cvv, se possui expiração de é internacional e etc$("#card-number").on('input', function() {card_flag();});})function card_flag(){PagSeguroDirectPayment.getBrand({cardBin: $("#card-number").val(),success: function (response) {console.log(response);//Coloca qual a bandeira ao lado do numero$("#card-flag").html(response['brand']['name']);$("#card-flag").show();//Mostra as opções de parcelamento (passando o preço e a bandeira)showPaymentOptions(response['brand']['name'], $("#price").val());$("#card-options-box").show();//Mostra o campo CVV se o cartão exigirif(response['brand']['cvvSize'] > 0){$("#card-cvv-box").show();}},error: function (response) {console.log($("#card-number").val());console.log(response);$("#card-flag").hide();$("#card-cvv-box").hide();$("#card-options-box").hide();}});}//Função para pegar o token do cartão de crédito que será usado no checkoutfunction getCardToken(card_number, cvv, month, year){console.log(month);console.log(year);var params = {cardNumber: card_number,cvv: cvv,expirationMonth: month,expirationYear: year,success: function (response) {console.log(response);},error: function (response) {console.log(response);}}PagSeguroDirectPayment.createCardToken(params);}// Função para mostrar opções de pagamento para o usuáriofunction showPaymentOptions(flag, price){PagSeguroDirectPayment.getInstallments({amount: price,brand: flag,success: function (response) {$("#card-options").html("");$.each( response['installments'][flag], function( index, value ){$("#card-options").append($("").attr("value",value['quantity']).text("$"+value['installmentAmount']+" x "+value['quantity']+" - total: $"+value['totalAmount']));});},error: function (response) {console.log(response);},complete: function (response) {//tratamento comum para todas chamadas}});} - Agora rode novamente seu projeto:
1rails s - Acesse no seu browser ‘http://localhost:3000‘ e clique em comprar.
- Na página de finalização do pedido que abriu simule colocar um cartão de crédito (use os dados de sandbox, número 411111111111, cvv 123, email c56048717318@sandbox.pagseguro.com.br)
- Note que agora o js coloca a bandeira do cartão, mostra o cvv caso o cartão precise e mostra a segunda sessão depois dos dados:
1<a href="http://165.227.206.32/wp-content/uploads/2017/01/Captura-de-tela-de-2017-01-06-21-32-57-2.png"><img class="aligncenter size-full wp-image-1300" src="http://165.227.206.32/wp-content/uploads/2017/01/Captura-de-tela-de-2017-01-06-21-32-57-2.png" alt="captura-de-tela-de-2017-01-06-21-32-57" width="918" height="376" /></a>
- Crie um arquivo em ‘/app/assets/javascripts/pagseguro.js’ e cole o seguinte código dentro dele (lembre-se de ler os comentários no código para entender as funções):
Parte 4 – Recebendo Notificações
Sempre que uma transação muda de status no PagSeguro ele chama nossa aplicação através da URL de notificação que colocamos no método create do controller Order. Nesta parte nós vamos configurar um Controller para receber essa chamada e alterar o status do nosso Order baseado nisto.
- Vamos primeiro criar o Controller, rode:
1rails g controller notification create --skip-template-engine - Agora coloque o seguinte conteúdo dentro do Controller que foi criado em “/app/controller/notification_controller.rb”:
12345678910111213141516class NotificationController < ApplicationController skip_before_filter :authenticate_user!, :only => :createprotect_from_forgerydef createtransaction = PagSeguro::Transaction.find_by_notification_code(params[:notificationCode])status = ['Aguardando Pagamento', 'Em análise', 'Paga', 'Disponível', 'Em disputa', 'Devolvida', 'Cancelada']if transaction.errors.empty?order = Order.where(reference: transaction.reference).lastorder.status = status[transaction.status.id.to_i - 1]order.saveendrender nothing: true, status: 200endend - Agora no nosso arquivo “config/routes.rb” substitua esta rota “get ‘notification/create'” pela rota abaixo:
1post 'notification', to: 'notification#create'
Pronto, agora nós precisamos subir nosso APP para o heroku para pegar a URL que usaremos para as notificações, vamos lá \o/
Parte 5 – Subindo para o Heroku
Vamos subir nosso App para o heroku para que tenhamos uma URL válida para receber as notificações do PagSeguro:
- Visite no seu browser: https://onebitcode.com/christian-singles-dating-site/
- Crie uma conta caso você não possua.
salomon hookup login - Instale o heroku cli caso você não possua e faça o login (Para aprender a instalar acesse https://devcenter.heroku.com/articles/heroku-cli)
- Agora precisamos instalar o git no nosso repositório e fazer o commit das nossas mudanças, rode:
1git init
depois rode:
1git add .
depois rode:
1git commit -m 'PagSeguro' - Para criar nosso projeto no heroku rode:
1heroku create - Note que agora que você criou o APP ele mostrou no console a URL do seu projeto, guarde essa URL para podermos acessar e também para usarmos para receber a notificação:
* Neste caso nossa URL está em azul (https://secret-wave-53573.herokuapp.com/) - Agora antes de prosseguirmos, vá no seu arquivo “/app/controllers/order_controler.rb” e no método create dentro desta linha ” payment.notification_url = “sua_url_do_heroku/notification” ” coloque a URL para o seu projeto no heroku + /notification.
- Finalmente suba seu app rodando:
1git push heroku master - Agora rode as migrations do seu projeto:
1heroku run rake db:migrate - \o/ Pronto, finalmente nosso pequeno site que aceita pagamentos está no ar
Parte 6 – Testando Tudo Isto
Agora vamos fazer um teste para ver se está tudo funcionando como gostaríamos, como este é apenas um exemplo vamos testar em sandbox, então vamos ter que finalizar o pagamento manualmente pelo sandbox do PagSeguro.
- Visite a URL do seu site no heroku que você pegou no passo anterior, acesse a raiz dela. No meu caso https://secret-wave-53573.herokuapp.com/
1<a href="http://165.227.206.32/wp-content/uploads/2017/01/Captura-de-tela-de-2017-01-06-19-14-03-2.png"><img class="aligncenter size-full wp-image-1288" src="http://165.227.206.32/wp-content/uploads/2017/01/Captura-de-tela-de-2017-01-06-19-14-03-2.png" alt="captura-de-tela-de-2017-01-06-19-14-03" width="931" height="378" /></a>
*Está vazio porque ainda não criamos nenhum produto - Agora visite no seu browser url_do_seu_projeto_no_heroku/users/sign_up e crie uma conta para seu administrador do sistema (Em uma aplicação real você teria que impedir que outras pessoas criassem contas de administrador, mas estamos só fazendo um exemplo):
1<a href="http://165.227.206.32/wp-content/uploads/2017/01/Captura-de-tela-de-2017-01-06-19-16-05-2.png"><img class="aligncenter size-full wp-image-1289" src="http://165.227.206.32/wp-content/uploads/2017/01/Captura-de-tela-de-2017-01-06-19-16-05-2.png" alt="captura-de-tela-de-2017-01-06-19-16-05" width="342" height="435" /></a> - Agora você foi redirecionado para a página de criação de produtos, mas caso tenha fechado a Aba visite url_do_seu_projeto_no_heroku/products
- Usando esse CRUD, crie novos produtos com valores e nomes diferentes para poder testar depois:
1<a href="http://165.227.206.32/wp-content/uploads/2017/01/Captura-de-tela-de-2017-01-06-19-21-15-2.png"><img class="aligncenter size-full wp-image-1290" src="http://165.227.206.32/wp-content/uploads/2017/01/Captura-de-tela-de-2017-01-06-19-21-15-2.png" alt="captura-de-tela-de-2017-01-06-19-21-15" width="526" height="349" /></a> - Agora abra uma Aba anônima para usar um usuário que não está logado e visite a raiz do seu site no heroku, no meu caso https://secret-wave-53573.herokuapp.com/.
- Veja que a lista de produtos que você criou está lá, agora escolha um e clique em “Comprar Produto”:
1<a href="http://165.227.206.32/wp-content/uploads/2017/01/Captura-de-tela-de-2017-01-06-20-18-25-2.png"><img class="aligncenter size-full wp-image-1292" src="http://165.227.206.32/wp-content/uploads/2017/01/Captura-de-tela-de-2017-01-06-20-18-25-2.png" alt="captura-de-tela-de-2017-01-06-20-18-25" width="583" height="361" /></a> - Agora na página de pagamento preencha todos os campos, para o numero do cartão você pode usar:
- Pronto, agora finalize a compra \o/
- Visite a página que lista as suas orders (pedidos de compra) nessa URL url_do_seu_projeto_no_heroku/order/index
1<a href="http://165.227.206.32/wp-content/uploads/2017/01/Captura-de-tela-de-2017-01-06-20-57-37-2.png"><img class="aligncenter size-full wp-image-1297" src="http://165.227.206.32/wp-content/uploads/2017/01/Captura-de-tela-de-2017-01-06-20-57-37-2.png" alt="captura-de-tela-de-2017-01-06-20-57-37" width="547" height="391" /></a> - Como nós estamos na sandbox do PagSeguro, o pagamento não será concluído sozinho :(. Mas em um caso real ele seria concluído quando a operadora de cartão liberasse e o PagSeguro chamaria nosso Controller de notificação. Como ele não vai fazer isso, vamos fazer manualmente.
- Visite a página de transações do Pagseguro clicando aqui, e note que a transação que você acaba de fazer está lá:
- Clique na transação, e quando aparecer o menu clique em “alterar” para alterar manualmente o status da transação.
- Altere para “Pago” e dê ok.
- Agora vamos visitar novamente nossa página com a listagem dos orders e ver se o status mudou, visite a página: url_do_seu_projeto_no_heroku/order/index
1<a href="http://165.227.206.32/wp-content/uploads/2017/01/Captura-de-tela-de-2017-01-06-21-05-42-2.png"><img class="aligncenter size-full wp-image-1298" src="http://165.227.206.32/wp-content/uploads/2017/01/Captura-de-tela-de-2017-01-06-21-05-42-2.png" alt="captura-de-tela-de-2017-01-06-21-05-42" width="364" height="114" /></a> - Sucesso \o/, recebemos a notificação, verificamos se ela era verdadeira, verificamos o conteúdo dele e alteramos o status do pagamento. Finalmente conseguimos fazer nosso sistema de pagamento funcionar, parabéns!

Não perca nenhum conteúdo
Receba nosso resumo semanal com os novos posts, cursos, talks e vagas o/
CONCLUSÃO
Conseguimos criar nosso pequeno APP com sistema de pagamento, como você pode ter notado é um longo caminho mesmo quando simplificamos algumas partes, mas se você está construindo um APP que precisa receber dinheiro não tem jeito, vai ter que desenvolver essa parte no seu APP, espero que com esse tutorial se torne mais fácil.
Com algumas configurações a mais poderíamos também receber via Boleto que é uma das modalidades do PagSeguro. Caso você queira um Post futuro onde acrescentamos isso deixa um comentário abaixo 🙂
Nesse exemplo nós usamos a sandbox do PagSeguro que é a simulação da integração com o sistema real e simplificamos várias partes para acelerar o processo, quando você desenvolver seu projeto para production usando um meio de pagamento, inclua filtros nos inputs, verificações e meios para que sua aplicação seja segura.
Para saber mais acesse a documentação oficial do PagSeguro clicando aqui.
Como de costume o Código completo da aplicação está no Github, caso você queria clonar o código, clique aqui. Aproveita e me segue lá \o/
Se você ficou com dúvidas ou tem sugestões de posts para o Blog comenta aí em baixo ou me adiciona no Facebook clicando aqui.
Muito Obrigado,
Sua presença aqui é uma honra para mim,
Leonardo Scorza 🙂
Primeira vez no OneBitCode? Curtiu esse conteúdo?
O OneBitCode tem muito mais para você!
O OneBitCode traz conteúdos de qualidade, e em português, sobre programação com foco em Ruby on Rails e também JavaScript.
Além disso, aqui sempre levamos à você conteúdos valiosos sobre a carreira de programação, dicas sobre currículos, portfólios, perfil profissional, soft skills, enfim, tudo o que você precisa saber para continuar evoluindo como Programador(a)!
Fique por dentro de todos os conteúdos o/
Nossas redes sociais:
📹 • https://youtube.com/Onebitcode [Live todas as terças-feiras às 19h)
💻 • https://linkedin.com/company/onebitcode
🙂 • https://facebook.com/onebitcode
📱 • https://instagram.com/one_bit_code
🐦 • https://twitter.com/onebitcode
Nossos cursos:
🥇 • Programador Full Stack Javascript em 8 Semanas
💎 • Curso Completo de Ruby
⚙ • Minicurso: API Rails 5 Completo
🐞 • Minicurso de Testes para Ruby on Rails com RSpec
Espero que curta nossos conteúdos e sempre que precisar de ajuda, fala com a gente!
Estamos aqui para você 🙂
Bem-vindo à família OneBitCode o/
Valeu pela dica, funcionou quase perfeitamente no ruby 2.5.
Ao tentar buscar a notificação da transação (PagSeguro::Transaction.find_by_notification_code) da um erro no serializer ao converter um nulo em um BigDecimal[0], fiz um fork do projeto e tratei o erro[1].
Infelizmente o projeto está abandonado e ninguém está realizando os merges.
[0] https://comunidade.pagseguro.uol.com.br/hc/pt-br/community/posts/115005688807-BigDecimal-Error-Ruby-on-Rails
[1] https://github.com/correamarques/ruby
E ai Fabian, beleza?
Opa que bom que você conseguiu corrigir, se puder deixe a solução nos comentários para o pessoal.
Grande abraço
Ahhh agora que eu vi que você já deixou, show \o/
resolvou pra mim! obrigado!
Parabéns pelo artigo! ficou ótimo!
Opa, valeu \o/
Parabéns pelo exemplo. Muito legal. Com seu artigo, despois de tentar de muitos jeitos so logrou integar pagseguro com minha app. A documentação de pagseguro é muito chata e confusa. Obrigado mil
Funciona bem em sandbox mas em production mostra um erro: Forbidden
Olá, estou com o mesmo problema como você resolveu?
Olá amigo.
Achei curioso o seguinte:
Por que você preferiu gerar o modelo assim:
rails g model order product_id:integer (…)
E não assim:
rails g model order product_id:references (…)
A migração é semelhante, mas você pula os processos automágicos do Rails. Tem algum motivo especial?
Obrigado pelo artigo.
E ai David, como vai?
Rodar dessa forma “rails g model order product:references (…)” também funcionaria, não teve nenhum motivo especial a escolha de ir pelo outro caminho 🙂
Valeu pelo comentário
Aqui ta dando um erro em OderController#create, e aparece na tela:
“Erro No Pagamento Bad request
credit card token is required.
installment quantity is required.”
não entendi pq a variável ‘payment’ não recebe o token do cartão de crédito como parâmetro…tipo:
payment.token = params[:card_token], como aparece na documentação da gem.
Se eu tento isso, aparece um erro:
NoMethodError Exception: undefined method `token=’ for #
Descobri o erro que é pq existem algumas linhas de código que estão por engano comentadas e na mesma linha! A saber:
payment.reference = reference
payment.sender = { hash: params[:sender_hash], name: params[:name], email: params[:email] }
payment.credit_card_token = params[:card_token]
payment.holder = { name: params[:card_name], birth_date: params[:birthday], document: { type: “CPF”, value: params[:cpf] }, phone: { area_code: params[:phone_code], number: params[:phone_number] } }
payment.installment = { value: @product.price, quantity: 1 }
puts “=> REQUEST”
O meu deu o mesmo erro e até agora não consegui ajeitar
como eu ajeito isso? em que parte do código esta isso? qual o path?
Era o que eu estava pecisando, vlw demais