Post Top Ad

Your Ad Spot

jueves, 7 de mayo de 2020

Cómo integrar PayPal en PHP

En esta publicación, explicaré cómo usar PayPal para pagos únicos y cómo usar la Notificación de pago instantánea (IPN) para procesar pagos en su sitio web.
Cuando realice la prueba, no desea gastar dinero, aquí es donde entran las cuentas de sandbox. Las cuentas de sandbox le permiten simular transacciones sin gastar dinero, todo se simula. Las cuentas de sandbox le permiten ejecutar toda la transacción cuando llega el momento de cambiar a cuentas reales, es un caso de cambiar la cuenta y las URL utilizadas, un cambio rápido para hacer.

Cuentas Sandbox

Inicie sesión en su cuenta de PayPal en PayPal Developer [Cuentas de Sandbox - PayPal Developer] (https://developer.paypal.com/developer/accounts/) 
Debajo de Sandbox en la barra lateral izquierda, haga clic en Cuentas, aquí verá sus cuentas de sandbox generadas automáticamente si no tiene ningún clic para crear una cuenta.
Las cuentas predeterminadas son 1 personal y 1 comercial. Son perfectos para probar transacciones con PayPal.
Utiliza la cuenta personal para probar los pagos a la cuenta comercial. Para obtener la contraseña para cada clic, haga clic en la elipse en el extremo derecho y haga clic en ver / editar cuenta.

Formulario de PayPal

Para enviar datos de pago a una página de pago de PayPal, puede usar un formulario, hay muchos detalles sobre los documentos de PayPal [cómo do-i-add-paypal-checkout-to-my-custom-shopping-cart] (https: // www.paypal.com/uk/smarthelp/article/how-do-i-add-paypal-checkout-to-my-custom-shopping-cart-ts1200)
El formulario se publica en https://www.sandbox.paypal.com/cgi-bin/webscr para cuentas sandbox o para pagos normales, use https://www.paypal.com/cgi-bin/webscr
Si está enviando varios artículos, use las opciones del carrito:
<input type="hidden" name="cmd" value="_cart" />
<input type="hidden" name="upload" value="1" />
Solo para artículos individuales, entonces use 
<input type=“hidden” name=“cmd” value="_xclick">
Una vez dicho esto, el uso predeterminado del carrito se puede usar para elementos individuales y múltiples, por lo que debe mantener el código coherente.
Para vincular el pago de su cuenta comercial de PayPal, ingrese la dirección de correo electrónico de la cuenta a:
<input type="hidden" name="business" value="email@business.example.com" />
Datos básicos del formulario:
<form action="https://www.sandbox.paypal.com/cgi-bin/webscr" method="post" />
<input type="hidden" name="cmd" value="_cart" />
<input type="hidden" name="upload" value="1" />
<input type="hidden" name="business" value="email@business.example.com" />
Opciones adicionales:
Establecer la moneda:
<input type="hidden" name="currency_code" value="GBP" />
<input type="hidden" name="lc" value="UK" />
<input type="hidden" name="rm" value="2" />
Establezca una URL de retorno, aquí será a donde se dirige al usuario después de completar un pago.
La url de cancelación será donde se dirija al usuario después de cancelar un pago.
La URL de notificación es donde se envían las Notificaciones de pago instantáneas (IPN) después del pago
<input type="hidden" name="return" value="https://domain.com/thankyou" />
<input type="hidden" name="cancel_return" value="https://domain.com/cancel" />
<input type="hidden" name="notify_url" value="https://domain.com/ipn" />
<input type="hidden" name="charset" value="utf-8" />
Agregar elementos
Cada elemento tendrá un número al final, por ejemplo, imte_name_1 es el primer elemento que otro elemento tendría item_name_2 y así sucesivamente:
<input type="hidden" name="item_name_1" value="PC" />
<input type="hidden" name="item_number_1" value="0045" />
<input type="hidden" name="amount_1" value="500.00" />
<input type="hidden" name="quantity_1" value="1" />
Para el botón de pago puede usar la imagen de PayPal:
<input style="margin-top:10px;" type="image" src="http://www.paypal.com/en_US/i/btn/x-click-but01.gif" name="submit" alt="Make payments with PayPal - it's fast, free and secure!">
</form>
Poniendolo todo junto:
<form action="https://www.sandbox.paypal.com/cgi-bin/webscr" method="post" />
<input type="hidden" name="cmd" value="_cart" />
<input type="hidden" name="upload" value="1" />
<input type="hidden" name="business" value="email@business.example.com" />
<input type="hidden" name="currency_code" value="GBP" />
<input type="hidden" name="lc" value="UK" />
<input type="hidden" name="rm" value="2" />
<input type="hidden" name="return" value="https://domain.com/thankyou" />
<input type="hidden" name="cancel_return" value="https://domain.com/cancel" />
<input type="hidden" name="notify_url" value="https://domain.com/ipn" />
<input type="hidden" name="charset" value="utf-8" />
<input type="hidden" name="item_name_1" value="PC" />
<input type="hidden" name="item_number_1 value="0045" />
<input type="hidden" name="amount_1" value="500.00" />
<input type="hidden" name="quantity_1" value="1" />
<input style="margin-top:10px;" type="image" src="http://www.paypal.com/en_US/i/btn/x-click-but01.gif" name="submit" alt="Make payments with PayPal - it's fast, free and secure!">
</form>
Si bien esto funciona, lo abre al abuso, ¡cualquiera puede inspeccionar el formulario y cambiar cualquiera de los campos, como el precio, antes de pasar a PayPal! 
Lo que prefiero hacer es enviar los datos directamente desde una página PHP, de esta manera no se puede modificar antes de enviarlos a PayPal.
Publicar datos en PayPal
Los mismos datos de formulario todavía se usan con este enfoque, solo que no se presentan en un formulario, sino en una matriz:
$fields = [
    'cmd'           => '_cart',
    'upload'        => '1',
    'business'      => 'email@business.example.com',
    'currency_code' => 'GBP',
    'lc'            => 'UK',
    'rm'            => '2',
    'return'        => 'https://domain.com/thankyou',
    'cancel_return' => 'https://domain.com/cancel',
    'notify_url'    => 'https://domain.com/ipn'
];

//add items
$fields["item_name_1"]   = 'PC';
$fields["item_number_1"] = '0045';
$fields["amount_1"]      = '500.00';
$fields["quantity_1"]    = 1;

$fields["item_name_2"]   = 'Office Chair';
$fields["item_number_2"] = '0098';
$fields["amount_2"]      = '60.00';
$fields["quantity_2"]    = 1;

// Prepare query string
$query_string = http_build_query($fields);

header('Location: https://www.sandbox.paypal.com/cgi-bin/webscr?' . $query_string);
exit();
Esto enviará los datos de la matriz a la URL como una solicitud POST.
Para enviar un elemento personalizado como user_id, puede usar un campo personalizado:
$fields['custom'] = $user_id;
O parte de la matriz de campos inicial:
$fields = [
    'cmd'           => '_cart',
    'upload'        => '1',
    'business'      => 'email@business.example.com',
    'currency_code' => 'GBP',
    'lc'            => 'UK',
    'rm'            => '2',
    'return'        => 'https://domain.com/thankyou',
    'cancel_return' => 'https://domain.com/cancel',
    'notify_url'    => 'https://domain.com/ipn',
    'custom'        => $user_id
];
Recuerde cambiar la URL de sandbox y el campo empresarial cuando cambie a una cuenta real.
Para los usuarios de Laravel, el IPN se PUBLICARÁ en su punto final de notify_url. No tendrá un token CSRF para asegurarse de excluir la llamada de las comprobaciones de token CSRF yendo a app / Http / Middleware / VerifyCsrfToken.php y agregando el punto final a la matriz $ except:
class VerifyCsrfToken extends Middleware
{
    /**
     * The URIs that should be excluded from CSRF verification.
     *
     * @var array
     */
    protected $except = [
        'ipn'
    ];
}

Manejo de IPN

Una vez que se ha realizado el pago, se envía un IPN a la notificación_url especificada.
Primero, especifique el clima para usar sandbox con una Y para sí o cualquier otra cosa para No.
Recopila los datos POST
// Read POST data
$raw_post_data = file_get_contents('php://input');
$raw_post_array = explode('&', $raw_post_data);
$myPost = array();
foreach ($raw_post_array as $keyval) {
    $keyval = explode ('=', $keyval);
    if (count($keyval) == 2){
        $myPost[$keyval[0]] = urldecode($keyval[1]);
    }
}
Lea la publicación de PayPal y agregue CMD
$req = 'cmd=_notify-validate';
foreach ($myPost as $key => $value) {
    $value = urlencode($value);
    $req .= "&$key=$value";
}
Establecer la URL de PayPal
if (USE_SANDBOX == 'Y') {
    $paypal_url = "https://ipnpb.sandbox.paypal.com/cgi-bin/webscr";
} else {
    $paypal_url = "https://ipnpb.paypal.com/cgi-bin/webscr";
}
A continuación para confirmar el pago, se devuelve una solicitud a PayPal
$ch = curl_init($paypal_url);
curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $req);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($ch, CURLOPT_FORBID_REUSE, 1);
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLINFO_HEADER_OUT, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Connection: Close'));
$res = curl_exec($ch);
Si hay un error al conectar, lanza una excepción
if (curl_errno($ch) != 0) {
    
    throw new \Exception("Can't connect to PayPal to validate IPN message: ".curl_error($ch)); 
    
    return true;
}
Un pago exitoso se VERIFICARÁ en la carga útil de PayPal, así que verifique eso:
if (preg_match("/VERIFIED/", $res)) {
//payment complete, process order & send an email etc
}
Poniendolo todo junto:
define("USE_SANDBOX", 'Y');

// Read POST data
$raw_post_data = file_get_contents('php://input');
$raw_post_array = explode('&', $raw_post_data);
$myPost = array();
foreach ($raw_post_array as $keyval) {
    $keyval = explode ('=', $keyval);
    if (count($keyval) == 2){
        $myPost[$keyval[0]] = urldecode($keyval[1]);
    }
}
// read the post from PayPal system and add 'cmd'
$req = 'cmd=_notify-validate';
foreach ($myPost as $key => $value) {
    $value = urlencode($value);
    $req .= "&$key=$value";
}
if (USE_SANDBOX == 'Y') {
    $paypal_url = "https://ipnpb.sandbox.paypal.com/cgi-bin/webscr";
} else {
    $paypal_url = "https://ipnpb.paypal.com/cgi-bin/webscr";
}
$ch = curl_init($paypal_url);
curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $req);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($ch, CURLOPT_FORBID_REUSE, 1);
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLINFO_HEADER_OUT, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Connection: Close'));
$res = curl_exec($ch);

if (curl_errno($ch) != 0) {
    
    throw new \Exception("Can't connect to PayPal to validate IPN message: ".curl_error($ch)); 
    
    return true;
} else {

    if (preg_match("/VERIFIED/", $res)) {
        //payment complete, you should send en email here.
    } else {
        //IPN not verified, you should send en email here.
    }
}
curl_close($ch);

No hay comentarios.:

Publicar un comentario

Dejanos tu comentario para seguir mejorando!

outbrain

Páginas