E-commerce no WordPress utilizando

PayPal

e

PagSeguro

- Rafael Ehlers / @rafaehlers

WordPress → E-commerce

  • Custom Post Types (Produtos, Pedidos)
  • Meta Dados CPT (Produto, Pedido)
  • Categorias Hierárquicas
  • Menus
  • Tags
  • Páginas Estáticas
  • Busca
  • Comentários (Blog, Produtos)
  • Usuários (Clientes, Meus pedidos)
  • User Meta (Dados cliente)
  • wp_mail para enviar e-mails

Falta

  • Carrinho de compras (Session)
  • Integrar solução de pagamento

3

tipos de solução de pagamento

  • "Direto"
  • Gateway de Pagamentos
  • Intermediadores de Pagamento

"Direto"

Gateway de Pagamentos

Intermediadores de Pagamento

PayPal

  • Website Payments Standard (Form, carrinho no PayPal)
  • Website/PayPal Payments Pro (API, carrinho na loja)
    • Direct Payment (suporta Pagamento recorrente)
    • Express Checkout (suporta Pagamento recorrente)
      • Digital Goods (abre num lightbox)
  • Gateway Integration
    • Payflow Pro
    • Payflow Link
  • Sandbox (Para testes)

Express Checkout

  • SetExpressCheckout
    (para configurar uma transação Express Checkout, API →)
  • GetExpressCheckoutDetails
    (para obter detalhes de uma transação, API →)
  • DoExpressCheckoutPayment
    (para completar uma transação Express Checkout, API →)


Manual de Introdução ao Express Checkout →

Sistema de Inscrições

Loja

Cálculo de frete

  • WebService PagSeguro
  • Correios

WebService PagSeguro


if($peso <= 30000){
	require_once('pagseguro/frete.php');
    // Faça seu cálculo passando:		
    // CepOrigem
    // Peso (em quilos)
    // Valor
    // CepDestino
    $peso = ceil($peso/1000);
    $valor = number_format($valor, 2, ',', '.');
    $options = get_option('pe_options');
    $valorFrete = $frete->gerar($options['pagseguro_cep_origem'],$peso , $valor, $cep);	
}else{
    $valorFrete['erro'] = 'excedeu'; 
}
                    

Somente PayPal, PagSeguro não suporta!

Passo a Passo do Checkout

  1. No carrinho
    • IDs Produtos
    • Descrição
    • Peso
    • Valor
    • Quantidade
    • Valor do Frete
  2. Checkout
    • Endereços
    • Escolha do sistema de pagamento
    • POST no WP

... no WP

  1. Preparo as variáveis
  2. Monto array dos produtos
  3. Verifico situação do usuário
  4. Atualiza dados do usuário
  5. Cadastro Pedido no WP
  6. Checkout PagSeguro ou PayPal

paymentRequest → PagSeguro


// Checkout PagSeguro **********************
if(!is_null($forma_pagamento) && $forma_pagamento == 'pagseguro'){		
    require_once "PagSeguroLibrary/PagSeguroLibrary.php";
    
    $paymentRequest = new PagSeguroPaymentRequest();
    $paymentRequest->setReference($novo_pedido_id);
    $paymentRequest->setCurrency("BRL");
    $paymentRequest->setItems($pagseguro_itens);
    if(strtoupper($frete_escolhido) == 'SEDEX'){
        $CODIGO = PagSeguroShippingType::getCodeByType('SEDEX');
    }
    if(strtoupper($frete_escolhido) == 'PAC'){
        $CODIGO = PagSeguroShippingType::getCodeByType('PAC');
    }
    $paymentRequest->setShippingType($CODIGO);
    
    $paymentRequest->setShippingAddress(
        array(
            'postalCode' => str_replace('-','',$cep),
            'street' => $endereco,
            'number' => $numero,
            'complement' => $complemento,
            'district' => $bairro,
            'city' => $cidade,
            'state' => $estado,
            'country' => 'BRA',//$pais,
        )
    );
    
    $paymentRequest->setSender($nome, $email, $ddd, str_replace('-','',$telefone));
    
    $paymentRequest->setRedirectUrl("http://meusite.com.br/retorno/");
    
    try {			
        $credentials = PagSeguroConfig::getAccountCredentials(); 
        $url = $paymentRequest->register($credentials);
        wp_redirect($url);
        exit();
    } catch (PagSeguroServiceException $e) {
        wp_die($e->getMessage());
    }
}
                    

PagSeguroLibrary/config/PagSeguroConfig.php


$options = get_option('pe_options');

$PagSeguroConfig = array();

$PagSeguroConfig['environment'] = Array();
$PagSeguroConfig['environment']['environment'] = "production";

$PagSeguroConfig['credentials'] = Array();
$PagSeguroConfig['credentials']['email'] = $options['pagseguro_email']; //"your@email.com";
$PagSeguroConfig['credentials']['token'] = $options['pagseguro_token']; //"your_token_here";

$PagSeguroConfig['application'] = Array();
$PagSeguroConfig['application']['charset'] = "UTF-8"; // UTF-8, ISO-8859-1

$PagSeguroConfig['log'] = Array();
$PagSeguroConfig['log']['active'] = TRUE;
$PagSeguroConfig['log']['fileLocation'] = "../PagSeguro.txt";                    
                    

SetExpressCheckout → PayPal


// Checkout PayPal ****************************
if(!is_null($forma_pagamento) && $forma_pagamento == 'paypal'){
    require_once "paypal.php";
    $options = get_option('pe_options');
    
    $nvparray = array(
        'PAYMENTREQUEST_0_AMT' => $valor_pedido,
        'PAYMENTREQUEST_0_ITEMAMT' => $valor_itens,
        'PAYMENTREQUEST_0_SHIPPINGAMT' => $valor_frete,

        'PAYMENTREQUEST_0_PAYMENTACTION' => 'Sale',
        'PAYMENTREQUEST_0_CURRENCYCODE' => 'BRL',
        'LOCALECODE' => 'pt_BR',
        'SOLUTIONTYPE' => 'Sole',
            
        'RETURNURL' => $options['paypal_url_return'],
        'CANCELURL' => $options['paypal_url_cancel'],
        'PAYMENTREQUEST_0_NOTIFYURL' => $options['paypal_url_notify'],
        
        //'PAYMENTREQUEST_0_INVNUM' => $novo_pedido_id,
        'PAYMENTREQUEST_0_DESC' => $novo_pedido_id, //'Tipo de frete: '.$frete_escolhido.' - Pedido ID: '.$novo_pedido_id,
        'PAYMENTREQUEST_0_CUSTOM' => $novo_pedido_id, //
        
        //'LANDINGPAGE' => 'Billing', //Billing – Non-PayPal account
        'LANDINGPAGE' => 'Login', //Login – PayPal account login
        
        'REQCONFIRMSHIPPING' => '0',
        'NOSHIPPING' => '0',
        'ADDROVERRIDE' => '1',
        'ALLOWNOTE' => '1',
        
        'EMAIL' => $email,
        'BUYEREMAILOPTINENABLE' => '0',
        
        'PAYMENTREQUEST_0_SHIPTONAME' => $nome,
        'PAYMENTREQUEST_0_SHIPTOSTREET' => $endereco.' '.$numero.' '.$complemento,
        'PAYMENTREQUEST_0_SHIPTOSTREET2' => $bairro,
        'PAYMENTREQUEST_0_SHIPTOCITY' => $cidade,
        'PAYMENTREQUEST_0_SHIPTOSTATE' => $estado,
        'PAYMENTREQUEST_0_SHIPTOZIP' => str_replace('-','',$cep),
        'PAYMENTREQUEST_0_SHIPTOPHONENUM' => $ddd.str_replace('-','',$telefone),
        'PAYMENTREQUEST_0_SHIPTOCOUNTRYCODE' => $pais //'BR'
        //'TAXIDTYPE' => 'BR_CPF',
        //'TAXIDDETAILS' => '12345678901', //-> CPF
        //'TAXIDTYPE' => 'BR_CNPJ',
        //'TAXIDDETAILS' => '12345678901234', //-> CNPJ
    );
    
    $nvparray = $nvparray + $paypal_itens;
    
    $resArray = hash_call("SetExpressCheckout", $nvparray);
    if(is_array($resArray) && ($resArray['ACK'] == 'Success' || $resArray['ACK'] == 'SuccessWithWarning')){
        RedirectToPayPal($resArray["TOKEN"]);
    }else{ ERRO....
                    

Retorno → PagSeguro


// Retorno PagSeguro ***************
if($_GET['id_pagseguro']){
    unset($_SESSION['carrinho']);
    unset($_SESSION['cep']);
    session_destroy();	
    
    $id_pagseguro = esc_attr($_GET['id_pagseguro']);
    
    $l1 = new WP_Query(array('posts_per_page' => '-1', 'post_type'=> 'pedido', 'meta_key'=> 'pag_codigo_transacao', 'meta_value'=> $id_pagseguro)); 
    if($l1->have_posts()){ 
        
        $frete_escolhido = strtoupper(get_post_meta($l1->post->ID, 'frete_escolhido', TRUE));
        $email = get_post_meta($l1->post->ID, 'email', TRUE);
        
        if($frete_escolhido == 'SEDEX'){$prazo = "até 3 dias úteis após a postagem.";}
        if($frete_escolhido == 'PAC'){$prazo = "até 8 dias úteis após a postagem.";}	
        
        $subject = "Recibo do seu pedido"; 
        $msg = "Conteúdo do e-mail";
        wp_mail($email, $subject, $msg, $headers );
    }		
}                    
                    

Notificação → PagSeguro


if(isset($_POST['notificationCode']) && isset($_POST['notificationType'])){
    $code = (isset($_POST['notificationCode']) && trim($_POST['notificationCode']) !== ""  ? trim($_POST['notificationCode']) : null);
    $type = (isset($_POST['notificationType']) && trim($_POST['notificationType']) !== ""  ? trim($_POST['notificationType']) : null);
    
    if ( $code && $type ) {
        
        require_once "PagSeguroLibrary/PagSeguroLibrary.php";
        
        $notificationType = new PagSeguroNotificationType($type);
        $strType = $notificationType->getTypeFromValue();
        
        switch($strType) {
            
            case 'TRANSACTION':

                $credentials = PagSeguroConfig::getAccountCredentials(); 
                try {
                    $transaction = PagSeguroNotificationService::checkTransaction($credentials, $code);
                    $pedido_id = $transaction->getReference(); 
                    
                    $status = $transaction->getStatus(); 
                    $status = $status->getValue();
                    
                    $paymentMethod = $transaction->getPaymentMethod();
                    
                    $type = $paymentMethod->getType();  
                    $type = $type->getValue();
                    switch($type){
                        case '1':
                            $type = 'Cartão de crédito';
                            break;
                        case '2':
                            $type = 'Boleto';
                            break;
                        case '3':
                            $type = 'Débito online (TEF)';
                            break;
                        case '4':
                            $type = 'Saldo PagSeguro';
                            break;
                        case '5':
                            $type = 'Oi Paggo';
                            break;
                        default:
                            $type = 'Erro';
                            break;
                            
                    }
                    update_post_meta($pedido_id, 'pag_tipo_pagamento_tipo', $type);
                    
                    $code = $paymentMethod->getCode();
                    $code = $code->getValue();
                    switch($code){
                        case '101';
                            $code = 'Cartão de crédito Visa';
                            break;
                        case '102';
                            $code = 'Cartão de crédito MasterCard';
                            break;
                        case '103';
                            $code = 'Cartão de crédito American Express';
                            break;
                        case '104';
                            $code = 'Cartão de crédito Diners';
                            break;
                        case '105';
                            $code = 'Cartão de crédito Hipercard';
                            break;
                        case '106';
                            $code = 'Cartão de crédito Aura';
                            break;
                        case '107';
                            $code = 'Cartão de crédito Elo';
                            break;
                        case '201';
                            $code = 'Boleto Bradesco';
                            break;
                        case '202';
                            $code = 'Boleto Santander';
                            break;
                        case '301';
                            $code = 'Débito online Bradesco';
                            break;
                        case '302';
                            $code = 'Débito online Itaú';
                            break;
                        case '303';
                            $code = 'Débito online Unibanco';
                            break;
                        case '304';
                            $code = 'Débito online Banco do Brasil';
                            break;
                        case '305';
                            $code = 'Débito online Banco Real';
                            break;
                        case '306';
                            $code = 'Débito online Banrisul';
                            break;
                        case '401';
                            $code = 'Saldo PagSeguro';
                            break;
                        case '501';
                            $code = 'Oi Paggo';
                            break;
                        default:
                            $code = 'Erro';
                            break;

                    }
                    update_post_meta($pedido_id, 'pag_tipo_pagamento_codigo', $code);
                    
                    $date = $transaction->getDate(); 
                    update_post_meta($pedido_id, 'pag_data_criacao', $date);
                    
                    $lastEventDate = $transaction->getLastEventDate(); 
                    update_post_meta($pedido_id, 'pag_data_ultimo_evento', $lastEventDate);
                    
                    $codigo = $transaction->getCode(); 
                    update_post_meta($pedido_id, 'pag_codigo_transacao', $codigo);
                    
                    $grossAmount = $transaction->getGrossAmount(); 
                    update_post_meta($pedido_id, 'pag_valor_bruto', $grossAmount);
                    
                    $discountAmount = $transaction->getDiscountAmount(); 
                    update_post_meta($pedido_id, 'pag_valor_desconto', $discountAmount);
                    
                    $feeAmount = $transaction->getFeeAmount(); 
                    update_post_meta($pedido_id, 'pag_valor_taxas', $feeAmount);
                    
                    $netAmount = $transaction->getNetAmount(); 
                    update_post_meta($pedido_id, 'pag_valor_liquido', $netAmount);
                    
                    $extraAmount = $transaction->getExtraAmount(); 
                    update_post_meta($pedido_id, 'pag_valor_extra', $extraAmount);

                    $installmentCount = $transaction->getInstallmentCount(); 
                    update_post_meta($pedido_id, 'pag_parcelas_cc', $extraAmount);
                    
                    $items = $transaction->getItems(); 
                    update_post_meta($pedido_id, 'pag_array_itens', $items);
                    
                    switch($status){
                        case '1':
                            $termo = 'aguardando';
                            break;
                        case '2':
                            $termo = 'analise';
                            break;
                        case '3':
                            $termo = 'paga';
                            break;
                        case '4':
                            $termo = 'disponivel';
                            break;
                        case '5':
                            $termo = 'disputa';
                            break;
                        case '6':
                            $termo = 'devolvida';
                            break;
                        case '7':
                            $termo = 'cancelada';
                            break;
                    }
                    
                    $termo = term_exists($termo,'status');
                    if(is_array($termo)){
                        $termo = $termo['term_id'];
                        wp_set_post_terms($pedido_id, $termo, 'status');
                        
                        $estoque = get_post_meta($pedido_id, 'estoque_alterado',TRUE);
                        if($status == 3 && empty($estoque)){//diminui no estoque os produtos comprados pela quantidade comprada
                            $produtos = get_post_meta($pedido_id, 'produtos',TRUE);
                            foreach($produtos as $indice => $dados){
                                $indice = explode("-",$indice);
                                $prod = get_post($indice[0]);
                                $pr_cores = get_post_meta($prod->ID, 'pr_cores',TRUE);
                                $pr_cores[$indice[1]]['quantidade'] -= $dados['quantidade'];
                                update_post_meta($prod->ID, 'pr_cores', $pr_cores);
                            }
                            update_post_meta($pedido_id, 'estoque_alterado', 'true');
                        }
                        
                        $temp = array();
                        $temp = get_post_meta($pedido_id, 'pag_historico',TRUE);
                        if(!empty($temp) && is_array($temp)){
                            $temp = array($temp);
                            $historico = array(array('data' => $lastEventDate, 'status' => $termo));
                            $merge = array_merge($temp, $historico);							
                            update_post_meta($pedido_id, 'pag_historico', $merge);

                        }else{
                            $historico = array(array('data' => $lastEventDate, 'status' => $termo));
                            update_post_meta($pedido_id, 'pag_historico', $historico);
                        }

                    }
                    
                } catch (PagSeguroServiceException $e) {
                    wp_die($e->getMessage());
                }
                
                break;
            
            default:
                LogPagSeguro::error("Unknown notification type [".$notificationType->getValue()."]");
                
        }
        
    } else {
        
        LogPagSeguro::error("Invalid notification parameters.");
        
    }
}	
                    

IPN → PayPal


// Notificação PayPal **************
if($_POST['payment_status'] == 'Completed' && isset($_POST['custom'])){
    
    $req = http_build_query($_POST);
    
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL,'https://www.paypal.com/cgi-bin/webscr?cmd=_notify-validate');
    curl_setopt($ch, CURLOPT_VERBOSE, 1);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $req);
    $response = curl_exec($ch);
    
    $http_status = strval(curl_getinfo($ch, CURLINFO_HTTP_CODE));
    
    if (curl_errno($ch)){
        // moving to display page to display curl errors
          $curl_error_no = curl_errno($ch) ;
          $curl_error_msg = curl_error($ch);
          //Execute the Error handling module to display errors. 
    }else{
         //closing the curl
        curl_close($ch);
    }
    
    if($response == 'VERIFIED' && $http_status == '200'){
        
        $pedido_id = esc_attr($_POST['custom']);
        
        if(!get_post_status($pedido_id)){exit();} //post não existente
        
        update_post_meta($pedido_id, 'paypal_notificacao', $req);
        
        //muda status para pago
        $termo = term_exists('paga','status');
        if(is_array($termo)){
            $termo = $termo['term_id'];
            wp_set_post_terms($pedido_id, $termo, 'status');
            
            $estoque = get_post_meta($pedido_id, 'estoque_alterado',TRUE);
                
            if(empty($estoque)){//diminui no estoque os produtos comprados pela quantidade comprada
                $produtos = get_post_meta($pedido_id, 'produtos',TRUE);
                foreach($produtos as $indice => $dados){
                    $indice = explode("-",$indice);
                    $prod = get_post($indice[0]);
                    $pr_cores = get_post_meta($prod->ID, 'pr_cores',TRUE);
                    $pr_cores[$indice[1]]['quantidade'] -= $dados['quantidade'];
                    update_post_meta($prod->ID, 'pr_cores', $pr_cores);
                }
                update_post_meta($pedido_id, 'estoque_alterado', 'true');
            }
                    
            $temp = array();
            $temp = get_post_meta($pedido_id, 'pag_historico',TRUE);
            if(!empty($temp) && is_array($temp)){
                $temp = array($temp);
                $historico = array(array('data' => $_POST['payment_date'], 'status' => $termo));
                $merge = array_merge($temp, $historico);							
                update_post_meta($pedido_id, 'pag_historico', $merge);

            }else{
                $historico = array(array('data' => $_POST['payment_date'], 'status' => $termo));
                update_post_meta($pedido_id, 'pag_historico', $historico);
            }				
        }
        
    }
    else{//INVALID
        update_post_meta($pedido_id, 'paypal_notificacao', 'erro');
    }
}
                    

Plugins de apoio

Os 5 Maiores Plug-ins

Temas

THE END

Obrigado pela atenção!