WordPress y PayPal una introducción

Para este tutorial, realizaremos los pasos necesarios para integrar PayPal como su proveedor de servicios de pago para un sitio con tecnología de WordPress. Trabajando con tipos de correos personalizados, crearemos un carrito de compras básico y permitiremos que los pagos se realicen a través de PayPal. Si bien el ejemplo trabajado es funcional, debe tomar medidas adicionales para limpiar y almacenar datos cuando trabaje con pagos.


Introducción

Utilizaremos páginas WP-Admin personalizadas para ver pedidos, tipos de publicaciones personalizados para la creación de productos (clase CPT de Jeffrey Way) y plantillas de páginas personalizadas para ver productos, el carrito y el procesamiento. Nuestra función en bruto se creará en PHP y aplicaremos algunos estilos básicos con CSS.

Dentro de los fragmentos de código a continuación, algunas marcas pueden haber sido eliminadas para facilitar la lectura.

Para aquellos que opten por aquí, avancen para recoger $ 200 o saltar a la etapa 2 de este tutorial y beneficiarse de los datos de muestra.


Paso 1 WP-Admin y estructura de la página

Publicemos las páginas en WP-Admin que usaremos a lo largo del tutorial..

  1. Carro
  2. Productos
  3. Gracias

Volveremos a visitar estas páginas y asignaremos una plantilla personalizada a cada una más adelante..


Paso 2 Estructura del tema del niño

Ahora crearemos los directorios y archivos requeridos para nuestro proyecto..

Estamos haciendo un tema secundario de Twenty Ten aquí, solo necesitamos crear los archivos que modificaremos o crearemos desde cero. Cualquier otro que se requiera por ejemplo. footer.php WordPress llenará los espacios en blanco para nosotros.


Paso 3 Tipos de correos personalizados de Jeffrey Way

Trabajaremos con la clase de Jeffrey Way (requiere PHP 5.3) para crear un tipo de publicación personalizada del producto
que permitirá la creación de productos, y no publicaciones de blog que pretendan ser productos, a través de WP-Admin.

En el archivo /wppp/wppp/post_types.php agrega las siguientes piezas de código.

Primero incluiremos la clase..

include ('jw_custom_posts.php');

En segundo lugar, cree un nuevo tipo de publicación personalizada e identifique qué componentes de la página de escritura utilizar..

$ producto = nuevo JW_Post_type ('Producto', array ('apoya' => array ('título', 'editor', 'extracto', 'miniatura', 'comentarios')));

En tercer lugar, tenemos un campo específico que se adapta mejor con un campo de texto por sí solo. Precio.

$ product-> add_meta_box ('Información del producto', matriz ('Precio' => 'texto'));

Cuando todos juntos se verá así.

include ('jw_custom_posts.php'); $ producto = nuevo JW_Post_type ('Producto', array ('apoya' => array ('título', 'editor', 'extracto', 'miniatura', 'comentarios'))); $ product-> add_meta_box ('Información del producto', matriz ('Precio' => 'texto'));

Paso 5 Recuperar todos los productos

Los tipos de publicaciones personalizadas de WordPress son fantásticos y la implementación en clase de Jeffrey puede ser rápida. Se puede acceder a los datos personalizados muy rápidamente, al igual que lo haría con las publicaciones de blog dentro de "the loop".

Vamos a visitar wppp / tpl-products.php archivar y recuperar los productos.

// Nombre de la plantilla: Productos

Esta es una convención que WordPress requiere de nosotros para crear una plantilla personalizada. Siempre que el tema activo contenga este archivo, podemos asignarlo a cualquier página..

Continúa y asigna esta plantilla a la página de productos previamente publicada..

$ products = new WP_Query (array ('post_type' => 'product'));

A continuación creamos una nueva instancia de WP_Query y buscar
un post_type de "producto".

Utilizando WP_Query Tenemos acceso a muchas etiquetas de plantilla existentes dentro de WordPress.

Todo lo que se requiere ahora es recorrer los productos y generar los datos.

while ($ products-> have_posts ()): $ products-> the_post (); el título(); eco '

Precio: '; echo get_post_meta ($ post-> ID, 'product_info_price', true); eco '

'; the_post_thumbnail ('producto'); el extracto(); al final

get_post_meta (); recuperará los datos almacenados dentro de los campos personalizados, y dado que se agregó un meta box usando la clase de JW anteriormente, esto es lo que se debe usar para recuperar su valor.

Note que usamos "product_info_price" como el segundo parámetro para get_post_meta. Este es el nombre que se aplica a nuestro campo personalizado cuando se utiliza la clase CPT de JW. La convención parece ser nombre-de-post-tipo_info_field.


Paso 6 Recuperando un solo producto

WordPress servirá single-custom-post-type.php si existe un tipo de mensaje personalizado y un archivo single-custom-post-name.php Existe dentro del tema activo. Esto es útil cuando se crea una nueva plantilla para productos individuales.

Al igual que recuperar los múltiplos que podríamos utilizar WP_Query (para consultas personalizadas) y las etiquetas de plantilla que proporciona WordPress. Sin embargo, al ver un solo elemento, técnicamente ya no necesitamos un bucle o un personalizado WP_Query.

el cargo(); the_post_thumbnail ('producto'); el título(); echo get_post_meta ($ post-> ID, 'product_info_price', true); el contenido();

Una adición más a nuestro single-product.php archivo, un formulario que permitirá agregar este artículo a la sesión del carrito de compras.

Se han agregado dos campos ocultos a este formulario, 1 que almacenará la ID de publicación (o ID del producto) y la otra se usará un poco más tarde. También se establece una cantidad predeterminada de 1.


Paso 7 Agregar un elemento a la sesión

El botón "Agregar al carrito" reside en la página del producto individual como se ilustra en el paso anterior, después de que un usuario haya elegido agregar un producto, el formulario se enviará a la página del carrito.

Vamos a trabajar con el wppp / tpl-cart.php archivar ahora.

/ * NOMBRE DE PLANTILLA: Carrito * /

tpl-cart.php es una plantilla personalizada, por lo que debemos avisar a WordPress y asignar la plantilla a la página del carrito a través de WP-Admin.

if ($ _ POST ['wppp_product_id']): $ product_id = $ _POST ['wppp_product_id']; $ qty = $ _POST ['wppp_qty']; $ action = $ _POST ['wppp_action']; switch ($ action) case "add": $ _SESSION ['cart'] [$ product_id] = $ _SESSION ['cart'] [$ product_id] + $ qty; descanso; caso "vacío": unset ($ _ SESSION ['cart']); descanso; caso "eliminar": unset ($ _ SESSION ['cart'] [$ product_id]); descanso;  terminara si;

Ahora verificamos si se han enviado datos de publicación adecuados y si es cierto, almacenamos datos para mayor comodidad como variables.

Usando un interruptor para determinar la acción actual y procesar en consecuencia.

foreach ($ _ SESSION ['cart'] as $ product => $ qty): $ row = get_post ($ product); echo $ row-> post_name echo $ row-> post_title; echo get_post_meta ($ product, 'product_info_price', true); echo $ qty; echo number_format (get_post_meta ($ product, 'product_info_price', true) * $ qty, 2); endforeach

Para imprimir el carrito a la página, se utiliza un bucle para recorrer los datos de la sesión..

Mientras que en este bucle, buscamos datos legibles por humanos en lugar de la representación numérica de cada producto / publicación almacenada dentro de la sesión.

Para hacer esto get_post () es perfecto, lo que permite una forma rápida de consultar WordPress al pasar una ID de publicación. Los datos devueltos son una versión reducida de WP_Query y se almacena dentro $ fila.

$ fila ahora se puede imprimir en la página junto con un total acumulado que muestra el precio del producto multiplicado por la cantidad.

Dentro del bucle se coloca un formulario que, por conveniencia, permitirá al usuario eliminar un artículo por completo de su carrito..

Al usar el interruptor escrito anteriormente, una comprobación para el caso de "eliminar" permitirá que el elemento se elimine de la sesión.


Paso 8 Preparando para PayPal

PayPal proporciona varias formas de enviar y recuperar datos, usaremos Notificación de pago instantánea o IPN.

  • Sobre IPN
  • Prueba con guía de IPN

Para que PayPal calcule y procese cualquier transacción, los datos pueden enviarse mediante un formulario con campos que coincidan con las convenciones de nomenclatura y datos esperados que establece PayPal.
La guía de IPN se puede encontrar en el encabezado o en los menús de pie de página de paypal.com/ipn.

Sigamos adelante ... dentro tpl-cart.php, debajo de todo se agrega un formulario con los requisitos esenciales de PayPal.

$ qty):?>

Visite developer.paypal.com para un entorno de prueba y sandbox.

Una vez que haya iniciado sesión en su cuenta de desarrollador, podrá crear cuentas de comprador y vendedor de prueba y "Entrar en el sitio de prueba de sandbox".

Enviando el carrito a "https://www.sandbox.paypal.com/cgi-bin/webscr"permitirá el uso del entorno de prueba.

Si decide activarse, la URL de la acción del formulario simplemente cambiará a "https://www.paypal.com/cgi-bin/webscr".

desarrollador.paypal.com Puede ser un buggy y una experiencia lenta, tener paciencia. Escribiendo este tutorial tuve que esperar a que PayPal se corrigiera solo y regresara un par de horas más tarde..

  $ qty):?>      

Al igual que en el bucle de la sesión anterior, los datos se recuperan y se presentan con una combinación de PHP en bruto y una función de WordPress.

Siempre que envíe a PayPal el tipo de datos correcto, se procesará a través de IPN.

En el formulario anterior, nombre del producto, se envían todas las cantidades relacionadas y los precios de cada producto. PayPal realizará el cálculo esta vez para múltiplos según el precio por artículo y la cantidad.

        

Las "variables de transacción y notificación", como se describe en la Guía de IPN, se han implementado como campos de formulario ocultos, al igual que los otros tipos de variables dirigidas por PayPal.

Al pasar un correo electrónico a la entrada con un nombre de "negocio", se indica a PayPal qué cuenta es el vendedor. Aquí, por conveniencia, usamos el correo electrónico actual del administrador de WordPress..

negocio: dirección de correo electrónico o ID de cuenta del destinatario del pago (es decir, la
comerciante). Equivalente a los valores de receiver_email (si el pago es
enviado a la cuenta principal) y conjunto de negocios en el sitio web de pago
HTML.
- Guía de IPN -

Las 3 URL pasadas con el formulario (regreso, cancel_return y Notify_url) permite que los enlaces se coloquen dentro del proceso de pago cuando un usuario visita paypal.com desde el carrito. Los "cancelar"La URL se mostrará antes y durante la transacción, mientras que"regreso"se muestra después de la transacción.

Se podría decir que el campo más importante aquí es "Notify_url"que permite a un desarrollador escuchar las instrucciones de PayPal tras bambalinas a medida que el usuario procesa su transacción.

Cuando PayPal envía una respuesta a la ipn.php archivar los detalles de la transacción se pueden almacenar dentro de una base de datos, se pueden enviar correos electrónicos y presentar las descargas. Depende de usted procesar los datos utilizando métodos que reflejen el tipo de producto en venta..

Así que vamos a crear la tabla de base de datos en el ipn.php archivar y pasar a recuperar pedidos.


Paso 9 Base de datos

Para la velocidad de implementación un campo de texto largo para artículos ordenados se crea para almacenar los artículos comprados con cada pedido y la cantidad como datos serializados. Puede ser recomendable con una tienda en vivo para normalizar cualquier tabla de base de datos detrás de su tienda a 4NF o considerar el uso de un tipo de publicación personalizada al almacenar pedidos.


Paso 10 Pruebas

Ahora debería poder publicar nuevos productos, agregar un producto (s) a la sesión del carrito, ver la sesión del carrito de la compra y proceder a PayPal.

Después de que un cliente haya pagado por las mercancías en PayPal, ¿entonces qué? ¿Cómo podemos identificar si la transacción ha sido exitosa, qué bienes se han comprado y dónde deben enviarse??

En el Paso 8, las cuentas de comprador y vendedor se destacaron para compras de prueba.

Además, anteriormente "return_url"fue creado como un campo de formulario oculto dentro de tpl-cart.php, este archivo podría usarse si el usuario elige "Regresar al sitio del comerciante" después de la transacción en PayPal.

Bucear sobre los datos de la publicación mostrará lo que está pasando.

foreach ($ _ POST como $ key => $ value): echo '

Llave: '. $ clave'.

'; eco '

Valor: '. $ valor'.

'; endforeach

Este bucle imprimirá los datos devueltos de PayPal por correo. Puede decidir utilizar esto para almacenar datos, realmente no es práctico hacerlo.

Para llegar a la página de agradecimiento, esperamos que el usuario haga clic en "Volver al sitio web del comerciante" de PayPal. En el caso de que un usuario decida cerrar el navegador lo que entonces?

Debido a este escollo, todo lo que debe hacerse a través de tpl-Thankyou.php es vaciar el carrito y mostrar el contenido como se muestra a continuación.

/ * NOMBRE DE PLANTILLA: Página: Gracias * / session_destroy (); el cargo(); el título(); el contenido();

A continuación, se nos notifica de PayPal sin importar lo que el usuario decida hacer después del pago. Aquí es donde entra la "Notificación" de la Notificación de pago instantánea.

Cuando el formulario fue enviado inicialmente a PayPal "Notify_url"tenía un valor. Esto le indicó a PayPal que nos gustaría usar el archivo http://yoursite.com/wp-content/themes/wppp/ipn.php para la comunicación.

Con esto en mente, ahora podemos "escuchar" a PayPal (y no al usuario) para obtener actualizaciones sobre el estado y el proceso de pago. Vamos a crear ese archivo final y nombrarlo ipn.php.

$ req = 'cmd = _notify-validate'; foreach ($ _ POST como $ key => $ value): $ value = urlencode (stripslashes ($ value)); $ req. = "& $ key = $ value"; endforeach $ header. = "POST / cgi-bin / webscr HTTP / 1.0 \ r \ n"; $ header. = "Tipo de contenido: application / x-www-form-urlencoded \ r \ n"; $ header. = "Content-Length:". strlen ($ req). "\ r \ n \ r \ n"; $ fp = fsockopen ('ssl: //www.sandbox.paypal.com', 443, $ errno, $ errstr, 30); if (! $ fp): // HTTP ERROR else: fputs ($ fp, $ header. $ req); while (! feof ($ fp)): $ res = fgets ($ fp, 1024); $ fh = fopen ('result.txt', 'w'); fwrite ($ fh, $ res); fclose ($ fh); if (strcmp ($ res, "VERIFIED") == 0): // Asegúrese de que tenemos acceso a las funciones WP, es decir, WPDB include_once ($ _ SERVER ['DOCUMENT_ROOT']. '/ wp-load.php'); // Debes validar contra estos valores. $ firstName = $ _POST ['first_name']; $ lastName = $ _POST ['last_name']; $ payerEmail = $ _POST ['payer_email']; $ addressStreet = $ _POST ['address_street']; $ addressZip = $ _POST ['address_zip']; $ addressCity = $ _POST ['address_city']; $ productsBought = $ _POST ["]; $ txnID = $ _POST ['txn_id']; // Se usa para almacenar rápidamente los artículos comprados $ i = 1; foreach ($ _ POST como $ key => $ value): if ($ key == 'item_name'. $ i): $ products_bought [] = $ value; $ i ++; endif; endforeach; $ products = serialize ($ products_bought); $ wpdb-> insert ('Customers', array ('forename' = > $ firstName, 'surname' => $ lastName, 'email' => $ payerEmail, 'address_line_1' => $ addressStreet, 'postcode' => $ addressZip, 'town' => $ addressCity, 'items_ordered' => $ productos, 'created' => current_time ('mysql'), 'txn_id' => $ txnID, 'user_ip' => $ _SERVER ['REMOTE_ADDR']), array ('% s', // FORENAME '% s' , // APELLIDO '% s', // CORREO ELECTRÓNICO '% s', // DIRECCIÓN 1 '% s', // PCODE '% s', // CIUDAD '% s', // ORDENADO '% s', // ESTADO '% s', // CREADO '% s' // IP DEL USUARIO)) elseif (strcmp ($ res, "INVALID") == 0): // Es posible que prefiera almacenar la transacción incluso si falla. para mayor investigación. endif; endwhile; fclose ($ fp); endif;

El código anterior parece un poco atemorizante, puede ver cómo se ensambla mirando el código-sample.php simplificado en PayPal.

Sin explicar el ejemplo que PayPal ha dado como guía, escuchamos las respuestas VÁLIDAS o INVÁLIDAS y las procesamos en consecuencia. WPDB se utiliza para almacenar cualquier dato requerido devuelto por PayPal.

foreach ($ _ POST como $ key => $ value): if ($ key == 'item_name _'. $ i): $ products_bought [] = $ value; $ i ++; terminara si; endforeach

Este fragmento recorre los datos de la publicación y comprueba si el elemento actual es un item_name_x que sabemos que es el nombre de nuestro producto. Los datos luego se serializan y almacenan dentro de una matriz.

El método de inserción WPDB se usa más adelante para enviar los datos serializados junto con otros valores a la tabla de clientes.


Paso 12 WP-Admin Página de pedidos

Nuestro último paso consiste en crear una página de menú WP-Admin y llenar esa página con los datos de clientes / pedidos previamente almacenados.

Puede decidir crear una página de pedidos más sólida para permitir la paginación, marcar cada artículo para el envío, imprimir fácilmente las etiquetas de envío y cualquier otra cosa.

Sigamos las convenciones de estilo de WordPress y creemos una larga lista de pedidos razonablemente bien presentada.

define (ADMIN_URL, admin_url ()); // Función auxiliar wppp_orders () add_menu_page ('Pedidos', 'Pedidos', 'administrador', __FILE__, 'wppp_orders_page', ADMIN_URL.'images / generic.png '); 

add_menu_page () Se ejecuta con 6 parámetros de un posible 7..

  1. Título de la página
  2. Título del menú
  3. Rol del usuario
  4. URL para nuestra página de opciones. En lugar de competir por el rango, usamos la ubicación y el nombre del archivo
  5. Función para ejecutar al acceder a esta página.
  6. Icono para el menu

Se podría pasar un parámetro opcional "posición de menú" pero nuevamente no luchemos con otros Autores.

función wppp_orders_page () ?> 

Pedidos

A continuación se muestra una lista de todos los pedidos.

# Nombre Apellido Email Dirección Productos comprados Usuario ip
CARNÉ DE IDENTIDAD Nombre Apellido Email Dirección Productos comprados Usuario ip

Arriba, se crea una función y, dentro de, un marcado para mostrar las órdenes. Al agregar la nueva página del menú, esta función también se aprobó, lo que le indica a WordPress que ejecute este código al ver la página del menú correspondiente..

Utilizando wpdb Para dar salida a los pedidos será la etapa final..

función wppp_orders_page ()  

Pedidos

A continuación se muestra una lista de todos los pedidos.

get_results ("SELECT * FROM clientes"); ?> artículos ordenados); ?>
# Nombre Apellido Email Dirección Productos comprados Usuario ip
carné de identidad; ?> nombre; ?> apellido; ?> correo electrónico; ?> Dirección Línea 1; ?>, código postal; ?>, pueblo; ?>
    '. $ productos [$ i].''; endfor ?>
user_ip; ?>
Aún no hay pedidos.

Al enviar productos y cantidades a la base de datos, los datos se serializaron. Ahora es el momento de revertir eso con unserialize en cada iteración.

Un bucle anidado permite que cada línea de datos no serializados se divida y se muestre como elementos de lista.

add_action ('admin_menu', 'wppp_orders');

Finalmente las funciones creadas previamente se ejecutan usando el add_action función y la admin_menu acción específicamente. Para una lista completa de acciones visite la referencia de acción.


Conclusión

En este tutorial, se ha demostrado una combinación de mejores prácticas, hacks y técnicas, muchas de las cuales estarán abiertas al debate. Se ha omitido algún código y discusión en el tutorial, a saber adicional.css, y funciones.php.

adicional.css Se importa dentro de la hoja de estilo para Twenty Ten (style.css) y aplica algunos estilos básicos para la visualización a lo largo del ejemplo..

funciones.php requiere cualquier archivo para publicaciones personalizadas y para ver pedidos dentro de WP-Admin. También se establece un nuevo tamaño de imagen que recorta la miniatura del producto para que coincida.

Utilizamos la capacidad del menú de Twenty Ten para mostrar los enlaces del menú superior para "Productos" y "Carrito".

Háganos saber en los comentarios lo que piensa de esta introducción al uso de PayPal con WordPress.