Cargo único
Acepta pagos únicos con Efectivo
En esta documentación explicamos cómo aceptar pagos únicos con Efectivo a través del Component. Podrás utilizar todo el poder de nuestra API de Pagos con un front end pre-diseñado que se adapta a las necesidades de tu marca de tu negocio en línea.
Configurar tu Servidor
Instalar el SDK de Oxxo Pay
Instala el SDK de Oxxo Pay para el lenguaje de programación de tu preferencia.
dotnet add package DigitalFemsa.net
pip install digital_femsa
gem install digital_femsa
npm i digitalfemsa
go get -u DigitalFemsa
<dependency>
<groupId>io.Digitalfemsa</groupId>
<artifactId>digitalfemsa-java</artifactId>
<version>1.0.1</version>
<scope>compile</scope>
</dependency>
Crear un customer
Antes de realizar el cobro al usuario, necesitarás crear un Customer. Este Objeto permite representar a tu cliente en Oxxo Pay para realizar cobros a su nombre.
Con la siguiente llamada crearás un Customer y obtendrás un customer_id, los cuales deberás guardar para realizar cobros en el futuro a la misma persona si así lo requieres.
curl --location --request POST 'https://api.digitalfemsa.io/customers' \
--header 'Accept: application/vnd.app-v2.1.0+json' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer key_DwaOLXoX6YCGGvfNifZ3IPwi' \
--data-raw '{
"name": "Felipe Gomez",
"email": "[email protected]"
}'
using System.Collections.Generic;
using System.Diagnostics;
using DigitalFemsa.net.Api;
using DigitalFemsa.net.Client;
using DigitalFemsa.net.Model;
namespace Example
{
public class CreateCustomerExample
{
public static void Main()
{
Configuration config = new Configuration();
// Configure Bearer token for authorization: bearerAuth
config.AccessToken = "key_DwaOLXoX6YCGGvfNifZ3IPwi";
var apiInstance = new CustomersApi(config);
var customer = new(
name: "test dot",
phone: "+573143159063",
email: "[email protected]",
corporate: true,
planId: "plan_2tXx672QLQ68CkmMn",
defaultShippingContactId: "",
defaultPaymentSourceId: "",
customReference: "dotnet_12345678"
);
var acceptLanguage = "es"; // string | Use for knowing which language to use (optional) (default to es)
try
{
// Create customer
CustomerResponse result = apiInstance.CreateCustomer(customer, acceptLanguage);
Debug.WriteLine(result);
}
catch (ApiException e)
{
Debug.Print("Exception when calling CustomersApi.CreateCustomer: " + e.Message);
Debug.Print("Status Code: " + e.ErrorCode);
Debug.Print(e.StackTrace);
}
}
}
}
import digital_femsa
import time
from digital_femsa.rest import ApiException
from pprint import pprint
configuration = digital_femsa.Configuration(
access_token = os.environ["BEARER_TOKEN"]
)
with digital_femsa.ApiClient(configuration) as api_client:
api_instance = digital_femsa.CustomersApi(api_client)
customer = digital_femsa.Customer(
email='[email protected]',
name='Customer Name',
phone='5534343434'
)
accept_language = 'es'
try:
# Create Customer
api_response = api_instance.create_customer(customer, accept_language=accept_language)
print("The response of CustomersApi->create_customer:\n")
pprint(api_response)
except ApiException as e:
print("Exception when calling CustomersApi->create_customer: %s\n" % e)
require 'digital_femsa'
DigitalFemsa.locale = :es
DigitalFemsa.api_key = 'key_DwaOLXoX6YCGGvfNifZ3IPwi'
customer = DigitalFemsa::Customer.create(
{
name: 'Felipe Gomez',
email: '[email protected]'
}
)
import { CustomersApi, Configuration, Customer, CustomerResponse } from "digitalfemsa";
const apikey = "key_xxxxx";
const config = new Configuration({ accessToken: apikey });
const client = new CustomersApi(config);
const customer: Customer = {
name: "John Constantine",
email: "[email protected]",
phone: "+5215555555555"
}
client.createCustomer(customer).then(response => {
const customerResponse = response.data as CustomerResponse;
console.log(customerResponse.id);
}).catch(error => {
console.error("here", error);
});
package main
import (
"context"
"fmt"
"io"
"net/http"
"github.com/digitalfemsa/digitalfemsa-go"
)
func main() {
const acceptLanguage = "es"
cfg := digitalfemsa.NewConfiguration()
client := digitalfemsa.NewAPIClient(cfg)
ctx := context.WithValue(context.TODO(), digitalfemsa.ContextAccessToken, "key_DwaOLXoX6YCGGvfNifZ3IPwi")
req := digitalfemsa.Customer{
Name: "test dot",
Phone: "+573143159063",
Email: "[email protected]",
Corporate: digitalfemsa.PtrBool(true),
PlanId: digitalfemsa.PtrString("plan_2tXx672QLQ68CkmMn"),
CustomReference: digitalfemsa.PtrString("go_12345678"),
}
customer, response, err := client.CustomersApi.CreateCustomer(ctx).Customer(req).AcceptLanguage(acceptLanguage).Execute()
if err != nil {
panic(err)
}
if response.StatusCode != http.StatusCreated {
responseBody, err := io.ReadAll(response.Body)
if err != nil {
panic(err)
}
panic(fmt.Sprintf("response body: %s", responseBody))
}
fmt.Printf("customer: %v", customer)
}
import com.digitalfemsa.*;
import com.digitalfemsa.auth.*;
import com.digitalfemsa.model.*;
import com.digitalfemsa.CustomersApi;
public class CustomersApiExample {
public static void main(String[] args) {
ApiClient defaultClient = Configuration.getDefaultApiClient();
defaultClient.setBasePath("https://api.digitalfemsa.io");
// Configure HTTP bearer authorization: bearerAuth
HttpBearerAuth bearerAuth = (HttpBearerAuth) defaultClient.getAuthentication("bearerAuth");
bearerAuth.setBearerToken("BEARER TOKEN");
CustomersApi apiInstance = new CustomersApi(defaultClient);
Customer customer = new Customer(); // Customer | requested field for customer
customer.setName("Customer Name");
customer.setEmail("[email protected]");
customer.setPhone("55454545454");
String acceptLanguage = "es"; // String | Use for knowing which language to use
try {
CustomerResponse result = apiInstance.createCustomer(customer, acceptLanguage,null);
System.out.println(result);
} catch (ApiException e) {
System.err.println("Exception when calling CustomersApi#createCustomer");
System.err.println("Status code: " + e.getCode());
System.err.println("Reason: " + e.getResponseBody());
System.err.println("Response headers: " + e.getResponseHeaders());
e.printStackTrace();
}
}
}
Importante:
Si ya tienes un customer_id asociado al usuario al que quieres cobrar, no es necesario que realices este paso.
Crear una Orden
Agrega un endpoint en tu servidor para crear una Orden.
¿Qué es una Orden?
Una Orden representa la intención de compra de tu cliente. Incluye todos los detalles relacionados a ella, como métodos de pago, información de envío, lista de productos a comprar, cargos, descuentos, impuesto, etc.
La orden requiere de cierta información que se obtiene ya sea de algún servicio interno del negocio, o directamente del FrontEnd al solicitarla al usuario/cliente final. Los datos principales traducidos a atributos del request son:
- ¿Quién está pagando? -> Customer
- ¿Qué está pagando? -> Line_items
- ¿Cuánto está pagando? -> Unit_pice multiplicado por Quantity
- ¿Cuál es el método de pago? -> Payment_method
- ¿Información extra requerida por el negocio? -> Metadata
Al iniciar, agrega el endpoint en tu servidor para crear una Orden.
Habilitar el método de pago de Efectivo
Habilita efectivo como método de pago usando el atributo allowed_payment_methods en el objeto Checkout de la orden al momento de crearla.
Para habilitar la opción de pago con Efectivo utiliza la palabra: "cash"
curl --location --request POST 'https://api.digitalfemsa.io/orders' \
--header 'Accept: application/vnd.app-v2.1.0+json' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer key_DwaOLXoX6YCGGvfNifZ3IPwi' \
--data-raw '{
"currency": "MXN",
"customer_info": {
"customer_id": "cus_2neG7CYEdeda9BBGU"
},
"line_items": [
{
"name": "Nintendo Switch OLED",
"unit_price": 9000000,
"quantity": 3
}
],
"checkout": {
"type": "Integration",
"allowed_payment_methods": ["cash"] //Habilita efectivo como metodo de pago
},
}'
using System.Collections.Generic;
using System.Diagnostics;
using DigitalFemsa.net.Api;
using DigitalFemsa.net.Client;
using DigitalFemsa.net.Model;
namespace Example
{
public class CreateOrderExample
{
public static void Main()
{
Configuration config = new Configuration();
// Configure Bearer token for authorization: bearerAuth
config.AccessToken = "key_DwaOLXoX6YCGGvfNifZ3IPwi";
var apiInstance = new OrdersApi(config);
var products = new()
{
new(
name: "Nintendo Switch OLED",
quantity: 3,
unitPrice: 9000000
)
};
var customerInfo = new(new CustomerInfoJustCustomerId("cus_2neG7CYEdeda9BBGU"));
var checkout = new CheckoutRequest(
type: "Integration",
allowedPaymentMethods: new List<string> {"cash"},
);
var orderRequest = new(
currency: "MXN",
customerInfo: customerInfo,
lineItems: products,
checkout: checkout
);
var acceptLanguage = "es"; // string | Use for knowing which language to use (optional) (default to es)
try
{
// Create order
OrderResponse result = apiInstance.CreateOrder(orderRequest, acceptLanguage);
Debug.WriteLine(result);
}
catch (ApiException e)
{
Debug.Print("Exception when calling OrdersApi.CreateOrder: " + e.Message);
Debug.Print("Status Code: " + e.ErrorCode);
Debug.Print(e.StackTrace);
}
}
}
}
import digital_femsa
import time
from digital_femsa.rest import ApiException
from pprint import pprint
configuration = digital_femsa.Configuration(
access_token = os.environ["BEARER_TOKEN"]
)
with digital_femsa.ApiClient(configuration) as api_client:
api_instance = digital_femsa.OrdersApi(api_client)
order = digital_femsa.OrderRequest(
currency='MXN',
customer_info=digital_femsa.OrderRequestCustomerInfo(
digital_femsa.CustomerInfoJustCustomerId(
customer_id='cus_2neG7CYEdeda9BBGU'
)
),
line_items=[digital_femsa.Product(
name='Nintendo Switch OLED',
quantity=3,
unit_price=9000000
)],
checkout=digital_femsa.CheckoutRequest(
type='Integration',
allowed_payment_methods=['cash']
)
)
accept_language = 'es'
try:
# Create Order
api_response = api_instance.create_order(order, accept_language=accept_language)
print("The response of OrdersApi->create_order:\n")
pprint(api_response)
except ApiException as e:
print("Exception when calling OrdersApi->create_order: %s\n" % e)
require 'digital_femsa'
require 'sinatra'
DigitalFemsa.locale = :es
DigitalFemsa.api_key = 'key_DwaOLXoX6YCGGvfNifZ3IPwi'
set :static, true
set :port, 9292
YOUR_DOMAIN = 'http://localhost:4242'.freeze
post '/create-order' do
order_params =
{
currency: 'MXN',
customer_info: {
customer_id: 'cus_2neG7CYEdeda9BBGU'
},
line_items: [
{
name: 'Nintendo Switch OLED',
unit_price: 9000000,
quantity: 3
}
],
checkout: {
type: 'Integration',
allowed_payment_methods: %w[cash], #Habilita todos los metodos de pago
}
}
order = DigitalFemsa::Order.create(order_params)
end
const express = require('express');
import { CustomersApi, Configuration,Product,ChargeRequest,OrderRequest, OrdersApi, Customer,CustomerInfoJustCustomerId, CustomerResponse } from "digitalfemsa";
const port = 9292;
const yourDomain = 'http://localhost:9292';
const app = express();
app.use(express.static('public'));
app.post('/create-order', async (_, res) => {
const config = new Configuration({ accessToken: "key_xxxxxxxx" });
const client = new OrdersApi(config);
const products: Array<Product> = [
{
name: "toshiba",
quantity: 1,
unit_price: 1555
}
];
const charges: Array<ChargeRequest> = [
{
payment_method: {
type: "cash"
}
}
];
const customer_info: CustomerInfoJustCustomerId = {
customer_id: "cus_2tKcHxhTz7xU5SymF"
};
const order_requet: OrderRequest = {
currency: "MXN",
customer_info: customer_info,
line_items: products,
charges: charges,
pre_authorize: false,
shipping_contact: {
address: {
street1: "Calle 123, int 2",
city: "Queretaro",
state: "Queretaro",
country: "mx",
postal_code: "76000",
residential: true
},
metadata: {}
},
}
const response = (await client.createOrder(order_requet, "es")).data;
});
app.listen(port, () => {
console.log(`Example app listening on port ${port}`);
});
package main
import (
"context"
"fmt"
"io"
"net/http"
"github.com/digitalfemsa/digitalfemsa-go"
)
func main() {
const acceptLanguage = "es"
cfg := digitalfemsa.NewConfiguration()
client := digitalfemsa.NewAPIClient(cfg)
ctx := context.WithValue(context.TODO(), digitalfemsa.ContextAccessToken, "key_DwaOLXoX6YCGGvfNifZ3IPwi")
product := digitalfemsa.Product{
Name: "Nintendo Switch OLED",
Quantity: 3,
UnitPrice: 9000000,
}
customer := digitalfemsa.NewCustomerInfoJustCustomerId("cus_2neG7CYEdeda9BBGU")
checkout := digitalfemsa.NewCheckoutRequest([]string{"cash"})
req := digitalfemsa.OrderRequest{
Checkout: checkout,
Currency: "MXN",
CustomerInfo: digitalfemsa.OrderRequestCustomerInfo{CustomerInfoJustCustomerId: customer},
LineItems: []digitalfemsa.Product{product},
}
order, response, err := client.OrdersApi.CreateOrder(ctx).OrderRequest(req).AcceptLanguage(acceptLanguage).Execute()
if err != nil {
panic(err)
}
if response.StatusCode != http.StatusCreated {
responseBody, err := io.ReadAll(response.Body)
if err != nil {
panic(err)
}
panic(fmt.Sprintf("response body: %s", responseBody))
}
fmt.Printf("order : %v", order)
}
import com.digitalfemsa.*;
import com.digitalfemsa.auth.*;
import com.digitalfemsa.model.*;
import java.util.Arrays;
public class Example {
public static void main(String[] args) {
ApiClient defaultClient = Configuration.getDefaultApiClient();
defaultClient.setBasePath("https://api.digitalfemsa.io");
// Configure HTTP bearer authorization: bearerAuth
HttpBearerAuth bearerAuth = (HttpBearerAuth) defaultClient.getAuthentication("bearerAuth");
bearerAuth.setBearerToken("BEARER TOKEN");
// Instance OrdersApi
OrdersApi apiInstance = new OrdersApi(defaultClient);
// Create CheckoutRequest
CheckoutRequest checkoutRequest = new CheckoutRequest();
checkoutRequest.setAllowedPaymentMethods(Arrays.asList("cash"));
// Create OrderRequestCustomerInfo with CustomerInfoJustCustomerId
OrderRequestCustomerInfo customerInfo = new OrderRequestCustomerInfo(new CustomerInfoJustCustomerId().customerId("cus_2neG7CYEdeda9BBGU"));
// Create Product
Product product = new Product();
product.setName("Nintendo Switch OLED");
product.setQuantity(3);
product.setUnitPrice(9000000);
// Create OrderRequest
OrderRequest orderRequest = new OrderRequest();
orderRequest.setCurrency("MXN");
orderRequest.setCheckout(checkoutRequest);
orderRequest.setCustomerInfo(customerInfo);
orderRequest.setLineItems(Arrays.asList(product));
String acceptLanguage = "es"; // String | Use for knowing which language to use
try {
OrderResponse result = apiInstance.createOrder(orderRequest, acceptLanguage, null);
System.out.println(result);
} catch (ApiException e) {
System.err.println("Exception when calling OrdersApi#createOrder");
System.err.println("Status code: " + e.getCode());
System.err.println("Reason: " + e.getResponseBody());
System.err.println("Response headers: " + e.getResponseHeaders());
e.printStackTrace();
}
}
}
Una vez creada la orden deberás obtener el Checkout ID asociado para inicializar el Component embebido en tu página de checkout.
Crear una página de pago en el cliente.
Inicializar el Component
Carga nuestro paquete de JavaScript para mantenerte en cumplimiento con PCI asegurando que los detalles de pago sean enviados directamente a Oxxo Pay sin pasar por tu servidor.
Inicializa el Component con tu Llave Pública para completar el pago desde el Cliente
<html>
<head>
<meta charset="utf-8" />
<title>Checkout</title>
<script
crossorigin
src="https://pay.digitalfemsa.io/v1.0/js/digitalfemsa-checkout.min.js"
></script>
<!-- En este archivo esta la config del componente -->
</head>
<body>
<div id="example" style="height: 714px"></div>
<script type="text/javascript">
const options = {
backgroundMode: 'lightMode', //lightMode o darkMode
colorPrimary: '#081133', //botones y bordes
colorText: '#585987', // títulos
colorLabel: '#585987', // input labels
inputType: 'minimalMode', // minimalMode o flatMode
};
const config = {
locale: 'es',
publicKey: '{{yourKey}}',
targetIFrame: '#example',
checkoutRequestId: '{{checkoutRequestId}}',
};
const callbacks = {
// Evento que notifica cuando finalizó la carga del component
onGetInfoSuccess: function (loadingTime) {
console.log('loading time en milisegundos', loadingTime.initLoadTime);
},
// Evento que notifica cuando finalizó el pago correctamente
onFinalizePayment: function (order) {
console.log('success: ', JSON.stringify(order));
},
// Evento que notifica cuando finalizó la carga del component
onErrorPayment: function (error) {
console.log('error en pago: ', error);
},
};
window.DigitalFemsaCheckoutComponents.Integration({
config,
callbacks,
options
});
</script>
</body>
</html>
El componente renderizado, deberá verse así en tu sitio o aplicación:
Con el Component inicializado en tu Checkout, tu cliente solo deberá ingresar la información requerida para pagos con efectivo y seguir las instrucciones para concretar la compra.
Por último, una vez confirmado el pago, se generará un evento onFinalizePayment en el Cliente el cual te mostrará la información de la orden y el cargo. En este momento podrás tomar decisiones relacionadas con el estado de la compra como re-direccionar a una página de pago exitoso o a una página con el resumen de la compra.
{
"id": "ord_2sxz1L8TSv8RufVZV",
"reference": "646180111812345678",
"charge": {
"id": "638e615afede9b001793237e",
"currency": "MXN",
"payment_method": {
"type": "cash"
},
"status": "pending_payment",
"customer_id": "",
"order_id": "ord_2sxz1L8TSv8RufVZV"
},
"metaData": {}
}
Servicio de Notificaciones
Oxxo Pay dispone de un servicio de notificaciones a usuario final que se activarán por default enviando mails a la dirección de correo que proporcionó el customer:
Notificación | Descripción | Vía |
---|---|---|
Generación de la referencia | Cuando se genera la referencia se envía un mail con la información de la misma y las instrucciones, para que el usuario final acuda a una de las tiendas de conveniencia a realizar el pago | |
Pago de la referencia | Cuando el usuario final realiza el pago, se envía un aviso de transacción exitosa. | |
Expiración de la referencia | Cuando la referencia expira y ya no tiene validez | Webhook |
Cancelación de la referencia | Cuando canceles la referencia se le enviará un mail al usuario final | Webhook |
A continuación podrás encontrar los ejemplos de las notificaciones que se envían a tu cliente.
Notificación: Generación de la referencia - Pagos en OXXO
Notificación: Pago de la referencia
Notificación: Expiración de la Referencia
Notificación: Cancelación de la referencia
Capturar eventos del pago
Automatiza tus procesos a través de los eventos que se generan en el flujo de pago. Para recibir estos eventos y ejecutar acciones sigue la guía de webhooks
Te recomendamos capturar los siguientes eventos:
Evento | Descripción |
---|---|
order.paid | Enviado cuando el cliente completa un pago de forma exitosa |
order.pending_payment | Enviado cuando una orden es creada pero está pendiente de pago |
order.declined | Enviado cuando el pago de una orden es declinado. |
Al capturar estos eventos podrás tomar acciones postventa como:
- Ejecutar un flujo de logística.
- Actualizar tus bases de datos de órdenes.
- Actualizar tus sistemas contables.
Updated 4 months ago