Products API
Endpoints to manage product inventory, from its creation, listing, details, and update.
Create a product​
POST /v1/products/
name
and price
fields are required. currency
is optional; if not present CRC
will be saved.
- Curl
- Python
- Angular
- Javascript
curl --location 'https://api.4geeks.io/v1/products/' \
--form 'name="Producto #1"' \
--form 'price="55"' \
--form 'currency="USD"'
import requests
url = "https://api.4geeks.io/v1/products/"
payload={'name': 'Producto #1',
'price': '55',
'currency': 'USD'}
files=[]
headers = {}
response = requests.request("POST", url, headers=headers, data=payload, files=files)
import { HttpClient } from "@angular/common/http";
import { Injectable } from "@angular/core";
import { Observable } from "rxjs";
@Injectable({
providedIn: "root",
})
export class ProductService {
url = "https://api.4geeks.io/v1/products/";
constructor(private http: HttpClient) {}
createProduct(): Observable<any> {
var formdata = new FormData();
formdata.append("name", "Producto #1");
formdata.append("price", "55");
formdata.append("currency", "USD");
return this.http.post<any>(url, formdata);
}
}
var formdata = new FormData();
formdata.append("name", "Producto #1");
formdata.append("price", "55");
formdata.append("currency", "USD");
var requestOptions = {
method: "POST",
body: formdata,
redirect: "follow",
};
fetch("https://api.4geeks.io/v1/products/", requestOptions)
.then((response) => response.text())
.then((result) => console.log(result))
.catch((error) => console.log("error", error));
Response will return the product id which you can make all the queries you need, such as using the product in Payment Links, to generate Payment logs, and future services provided by 4Geeks.
{
"code": 201,
"title": "Complete registration",
"content": "The registration was successfully completed.",
"type": "success",
"data": {
"id": "5c46d97b-22d5-4917-8833-3a61385d7c27"
}
}
Recurrence​
La recurrencia funciona para servicios como Payment Links, y el cual le brinda la funcionalidad de recurrencia en su cobro
Hay dos tipos de recurrencia:
1- Recurrencia por dia especifico de cobro
La cual se caracteriza por realizar el cobro en un dia especifico del mes a los clientes que tengas asociado a un Payment Link, los dÃas pueden ir del 1
al 28
del mes
Ejemplo: Si deseas crear un producto de cobro a un cliente y este debe pagar todos los meses especÃficamente los dÃas 15
2- Recurrencia por periodo
La caracterÃstica de este tipo de recurrencia es que a diferencia de la anterior esta puede ser configurada en periodos de meses.
Ejemplo: Si deseas crear un producto de cobro bimensual a un cliente, este cliente al pagar se le enviara una nueva notificación dentro de 2 meses, y asi sucesivamente.
Este tipo de recurrencia puede tener los valores de 1
,2
,3
,4
,6
,12
los cuales son valores en meses.
Como configurar la recurrencia
Para configurar la recurrencia se debe hacer cuando se crea un producto nuevo. La recurrencia es un objeto json que contiene la configuración de periodo o dia de cobro, asi como el tipo.
Ejemplos:
Recurrencia por dia especifico de cobro
{
"recurrence": "specific_billing_day",
"payday": 1
}
payday
es el dia de cobro y recurrence
el tipo de recurrencia
Recurrencia por periodo
{
"recurrence": "period",
"duration_period": 1
}
duration_period
en este caso es el periodo en meses los valores permitidos son 1
,2
,3
,4
,6
,12
Bueno, una ves generado el JSON
se puede proceder a crear un producto:
- Curl
- Python
- Angular
- Javascript
curl --location 'https://api.4geeks.io/v1/products/' \
--form 'name="Membresia Mensual Gym Musculitos"' \
--form 'price="8500"' \
--form 'recurrence="{
\"recurrence\": \"period\",
\"duration_period\": 1
}"'
import requests
url = "https://api.4geeks.io/v1/products/"
payload={'name': 'Membresia Mensual Gym Musculitos',
'price': '8500',
'recurrence': {
"recurrence": "period",
"duration_period": 1
}}
files=[
]
headers = {}
response = requests.request("POST", url, headers=headers, data=payload, files=files)
import { HttpClient } from "@angular/common/http";
import { Injectable } from "@angular/core";
import { Observable } from "rxjs";
@Injectable({
providedIn: "root",
})
export class ProductService {
url = "https://api.4geeks.io/v1/products/";
constructor(private http: HttpClient) {}
createProduct(): Observable<any> {
var formdata = new FormData();
formdata.append("name", "Membresia Mensual Gym Musculitos");
formdata.append("price", "8500");
formdata.append(
"recurrence",
'{\n "recurrence": "period",\n "duration_period": 1\n}'
);
return this.http.post<any>(url, formdata);
}
}
var formdata = new FormData();
formdata.append("name", "Membresia Mensual Gym Musculitos");
formdata.append("price", "8500");
formdata.append(
"recurrence",
'{\n "recurrence": "period",\n "duration_period": 1\n}'
);
var requestOptions = {
method: "POST",
body: formdata,
redirect: "follow",
};
fetch("https://api.4geeks.io/v1/products/", requestOptions)
.then((response) => response.text())
.then((result) => console.log(result))
.catch((error) => console.log("error", error));
En caso de que su sistema no permita enviar un archivo JSON
puedes convertirlo a un objeto de tipo String
para el envió
Respuesta del servidor
{
"code": 201,
"title": "Complete registration",
"content": "The registration was successfully completed.",
"type": "success",
"data": {
"id": "73931315-cf8c-46bd-9f89-9b5b16612534"
}
}
Si realizamos la consulta de los detalles obtendremos lo siguiente:
{
"id": "73931315-cf8c-46bd-9f89-9b5b16612534",
"name": "Membresia Mensual Gym Musculitos",
"short_description": null,
"description": null,
"stock": 0,
"price": 8500.0,
"currency": "crc",
"is_physical": false,
"bar_code": null,
"sku": null,
"recurrence": {
"recurrence": "period",
"duration_period": 1
},
"images": {
"images": [],
"default": ""
},
"payment_link": false,
"test": true,
"total_price": 8500.0,
"taxes": []
}
Como se indico anteriormente la recurrencia solo puede ser configurada cuando se crea el producto
Impuestos​
Los impuestos pueden ser asociados al producto cuando se crear o se actualiza el producto
Crear un impuesto: POST /v1/taxes/
- Curl
- Python
- Angular
- Javascript
curl --location 'https://api.4geeks.io/v1/taxes/' \
--form 'name="Servicios Educativos Especial"' \
--form 'value="13"
import requests
url = "https://api.4geeks.io/v1/taxes/"
payload={'name': 'Servicios Educativos Especial',
'value': '13'}
files=[
]
headers = {}
response = requests.request("POST", url, headers=headers, data=payload, files=files)
import { HttpClient } from "@angular/common/http";
import { Injectable } from "@angular/core";
import { Observable } from "rxjs";
@Injectable({
providedIn: "root",
})
export class ProductService {
url = "https://api.4geeks.io/v1/taxes/";
constructor(private http: HttpClient) {}
createProduct(): Observable<any> {
var formdata = new FormData();
formdata.append("name", "Servicios Educativos Especial");
formdata.append("value", "13");
return this.http.post<any>(url, formdata);
}
}
var formdata = new FormData();
formdata.append("name", "Servicios Educativos Especial");
formdata.append("value", "13");
var requestOptions = {
method: "POST",
body: formdata,
redirect: "follow",
};
fetch("https://api.4geeks.io/v1/taxes/", requestOptions)
.then((response) => response.text())
.then((result) => console.log(result))
.catch((error) => console.log("error", error));
El campo value
es un porcentaje que permite también decimales, la lectura correcta seria impuesto del 13% a Servicios Educativos Especial
Respuesta del servidor
{
"code": 201,
"title": "Complete registration",
"content": "The registration was successfully completed.",
"type": "success",
"data": {
"id": 9
}
}
Listado de impuestos: GET /v1/taxes/
- Curl
- Python
- Angular
- Javascript
curl --location 'https://api.4geeks.io/v1/taxes/'
import requests
url = "https://api.4geeks.io/v1/taxes/"
payload={}
files=[
]
headers = {}
response = requests.request("GET", url, headers=headers, data=payload, files=files)
import { HttpClient } from "@angular/common/http";
import { Injectable } from "@angular/core";
import { Observable } from "rxjs";
@Injectable({
providedIn: "root",
})
export class ProductService {
url = "https://api.4geeks.io/v1/taxes/";
constructor(private http: HttpClient) {}
listProduct(): Observable<any> {
return this.http.get<any>(url);
}
}
var requestOptions = {
method: "GET",
redirect: "follow",
};
fetch("https://api.4geeks.io/v1/taxes/", requestOptions)
.then((response) => response.text())
.then((result) => console.log(result))
.catch((error) => console.log("error", error));
Respuesta del servidor
[
{
"id": 1,
"name": "iva",
"value": 3
},
{
"id": 8,
"name": "Servicios Educativos",
"value": 15
},
{
"id": 9,
"name": "Servicios Educativos Especial",
"value": 13
}
]
Actualización de impuestos: PUT /v1/taxes/
Los impuestos pueden ser actualizados uno por uno, o en bloque
Actualización de un único impuesto, se envÃa el siguiente JSON
:
{
"taxes":{
"id": 1,
"name": "iva",
"value": 10.0
}
}
Actualización en bloques de impuestos, se envÃa el siguiente JSON
:
{
"taxes": [
{
"id": 1,
"name": "iva",
"value": 10.0
},
{
"id": 9,
"name": "Servicios Educativos Especial",
"value": 13.0
},
{
"name": "Membresias IVA",
"value": 15.0
}
]
}
Ejemplo enviando el segundo JSON
:
- Curl
- Python
- Angular
- Javascript
curl --location --request PUT 'localhost:8001/v1/taxes/' \
--data '{
"taxes": [
{
"id": 1,
"name": "iva",
"value": 10.0
},
{
"id": 9,
"name": "Servicios Educativos Especial",
"value": 13.0
},
{
"name": "Membresias IVA",
"value": 15.0
}
]
}'
import requests
url = "https://api.4geeks.io/v1/taxes/"
payload = {
"taxes": [
{
"id": 1,
"name": "iva",
"value": 10.0
},
{
"id": 9,
"name": "Servicios Educativos Especial",
"value": 13.0
},
{
"name": "Membresias IVA",
"value": 15.0
}
]
}
headers = {}
response = requests.request("PUT", url, headers=headers, data=payload)
import { HttpClient } from "@angular/common/http";
import { Injectable } from "@angular/core";
import { Observable } from "rxjs";
@Injectable({
providedIn: "root",
})
export class ProductService {
url = "https://api.4geeks.io/v1/taxes/";
constructor(private http: HttpClient) {}
createProduct(): Observable<any> {
var formdata = new FormData();
formdata.append(
"taxes",
'[\n
{\n
"id": 1,\n
"name": "iva",\n
"value": 10.0\n
},\n
{\n
"id": 9,\n
"name": "Servicios Educativos Especial",\n
"value": 13.0\n
},\n
{\n
"name": "Membresias IVA",\n
"value": 15.0\n
}\n
]'
);
return this.http.put<any>(url, formdata);
}
}
var raw ={
"taxes": [
{
"id": 1,
"name": "iva",
"value": 10.0
},
{
"id": 9,
"name": "Servicios Educativos Especial",
"value": 13.0
},
{
"name": "Membresias IVA",
"value": 15.0
}
]
};
var requestOptions = {
method: "PUT",
body: raw,
redirect: "follow",
};
fetch("https://api.4geeks.io/v1/taxes/", requestOptions)
.then((response) => response.text())
.then((result) => console.log(result))
.catch((error) => console.log("error", error));
En caso de que envies un impuesto sin ID
este impuesto sera tomado como uno nuevo y se procederá a su creación, siempre y cuando el nombre no se encuentre en uso ya
Respuesta del servidor
{
"code": 200,
"title": "Completed operation",
"content": "Taxes were created or updated correctly",
"type": "success"
}
Como agregar un impuesto a un producto:
Para agregar los impuestos a un producto se le pasan estos de la siguiente manera:
"taxes": "1,9"
En un objeto de tipo String
separados por ,
Tomaremos el producto que actualizamos anteriormente y ahora le agregaremos los 2 impuestos:
- Curl
- Python
- Angular
- Javascript
curl --location --request PUT 'https://api.4geeks.io/v1/products/5c46d97b-22d5-4917-8833-3a61385d7c27/' \
--form 'taxes: "1,9"'
import requests
url = "https://api.4geeks.io/v1/products/5c46d97b-22d5-4917-8833-3a61385d7c27/"
payload={'taxes': '1,9'}
files=[
]
headers = {}
response = requests.request("PUT", url, headers=headers, data=payload, files=files)
print(response.text)
import { HttpClient } from "@angular/common/http";
import { Injectable } from "@angular/core";
import { Observable } from "rxjs";
@Injectable({
providedIn: "root",
})
export class ProductService {
url = "https://api.4geeks.io/v1/products/";
constructor(private http: HttpClient) {}
updateProduct(id: String): Observable<any> {
var formdata = new FormData();
formdata.append( "taxes","1,9");
return this.http.put<any>(url, formdata);
}
}
var formdata = new FormData();
formdata.append( "taxes","1,9");
var requestOptions = {
method: "PUT",
body: formdata,
redirect: "follow",
};
fetch(
"https://api.4geeks.io/v1/products/5c46d97b-22d5-4917-8833-3a61385d7c27/",
requestOptions
)
.then((response) => response.text())
.then((result) => console.log(result))
.catch((error) => console.log("error", error));
respuesta del servidor
{
"code": 200,
"title": "Updated product",
"content": "The product was successfully updated.",
"type": "success",
"data": {
"id": "5c46d97b-22d5-4917-8833-3a61385d7c27",
"name": "Producto #1",
"short_description": "Producto dedicado a todas las edades",
"description": null,
"stock": 0,
"price": 55.0,
"currency": "USD",
"is_physical": false,
"bar_code": null,
"sku": null,
"recurrence": null,
"images": {
"images": [],
"default": ""
},
"payment_link": false,
"test": true,
"total_price": 73.15,
"taxes": [
{
"id": 1,
"name": "iva",
"value": 20.0
},
{
"id": 9,
"name": "Servicios Educativos Especial",
"value": 13.0
}
]
}
}
Puedes enviar el campo taxes
de la misma forma a la hora de crear el producto
El campo total_price
indica el precio del producto con los impuestos sumados
Imágenes en los productos​
Se deben enviar los archivo para las imágenes, esto puede ser enviado por medio de FormData
Los productos pueden tener 5 imágenes, 1 imagen principal y 4 secundarias
Ejemplo, quiero que mi producto tenga 3 imágenes:
- Curl
- Python
- Angular
- Javascript
curl --location --request PUT 'https://api.4geeks.io/v1/products/5c46d97b-22d5-4917-8833-3a61385d7c27/' \
--form 'image_default=@"/D:/Descargas/imagen_principal.png"' \
--form 'images=@"/D:/Descargas/imagen_3.png"' \
--form 'images=@"/D:/Descargas/imagen_2.jpg"'
import requests
url = "https://api.4geeks.io/v1/products/5c46d97b-22d5-4917-8833-3a61385d7c27/"
payload={}
files=[
('image_default',('imagen_principal.png',open('/D:/Descargas/imagen_principal.png','rb'),'image/png')),
('images',('imagen_3.png',open('/D:/Descargas/imagen_3.png','rb'),'image/png')),
('images',('imagen_2.jpg',open('/D:/Descargas/imagen_2.jpg','rb'),'image/jpeg'))
]
headers = {}
response = requests.request("PUT", url, headers=headers, data=payload, files=files)
print(response.text)
import { HttpClient } from "@angular/common/http";
import { Injectable } from "@angular/core";
import { Observable } from "rxjs";
@Injectable({
providedIn: "root",
})
export class ProductService {
url = "https://api.4geeks.io/v1/products/";
constructor(private http: HttpClient) {}
updateProduct(id: String): Observable<any> {
var formdata = new FormData();
formdata.append("image_default", fileInput.files[0], "/D:/Descargas/imagen_principal.png");
formdata.append("images", fileInput.files[0], "/D:/Descargas/imagen_3.png");
formdata.append("images", fileInput.files[0], "/D:/Descargas/imagen_2.jpg");
return this.http.put<any>(url, formdata);
}
}
var formdata = new FormData();
formdata.append("image_default", fileInput.files[0], "/D:/Descargas/imagen_principal.png");
formdata.append("images", fileInput.files[0], "/D:/Descargas/imagen_3.png");
formdata.append("images", fileInput.files[0], "/D:/Descargas/imagen_2.jpg");
var requestOptions = {
method: 'PUT',
body: formdata,
redirect: 'follow'
};
fetch(
"https://api.4geeks.io/v1/products/5c46d97b-22d5-4917-8833-3a61385d7c27/",
requestOptions
)
.then((response) => response.text())
.then((result) => console.log(result))
.catch((error) => console.log("error", error));
respuesta del servidor
{
"code": 200,
"title": "Updated product",
"content": "The product was successfully updated.",
"type": "success",
"data": {
"id": "5c46d97b-22d5-4917-8833-3a61385d7c27",
"name": "Producto #1",
"short_description": "Producto dedicado a todas las edades",
"description": null,
"stock": 0,
"price": 55.0,
"currency": "USD",
"is_physical": false,
"bar_code": null,
"sku": null,
"recurrence": null,
"images": {
"default": "https://storage.googleapis.com/g-payments.appspot.com/img/2875-Producto%20%231-1677265824-default.png",
"images": [
{
"image": "https://storage.googleapis.com/g-payments.appspot.com/img/2875-Producto%20%231-1677265826-image%201.png"
},
{
"image": "https://storage.googleapis.com/g-payments.appspot.com/img/2875-Producto%20%231-1677265828-image%202.jpeg"
}
]
},
"payment_link": false,
"test": true,
"total_price": 73.15,
"taxes": [
{
"id": 1,
"name": "iva",
"value": 20.0
},
{
"id": 9,
"name": "Servicios Educativos Especial",
"value": 13.0
}
]
}
}
En caso de querer modificar una imagen deben volverse a enviar todos los archivos
En caso en caso de querer eliminar las imágenes se envÃan los campos imagen_default
y images
con un objeto de tipo string
vació ""
Get a product​
GET /v1/products/<id>/
Los detalles de un producto se pueden consultar de la siguiente manera:
- Curl
- Python
- Angular
- Javascript
curl --location 'https://api.4geeks.io/v1/products/5c46d97b-22d5-4917-8833-3a61385d7c27/'
import requests
url = "https://api.4geeks.io/v1/products/5c46d97b-22d5-4917-8833-3a61385d7c27/"
payload={}
headers = {}
response = requests.request("GET", url, headers=headers, data=payload)
import { HttpClient } from "@angular/common/http";
import { Injectable } from "@angular/core";
import { Observable } from "rxjs";
@Injectable({
providedIn: "root",
})
export class ProductService {
url = "https://api.4geeks.io/v1/products/";
constructor(private http: HttpClient) {}
detailsProduct(id: String): Observable<any> {
return this.http.get<any>(`${url}${id}/`);
}
}
var requestOptions = {
method: "GET",
redirect: "follow",
};
fetch(
"https://api.4geeks.io/v1/products/5c46d97b-22d5-4917-8833-3a61385d7c27/",
requestOptions
)
.then((response) => response.text())
.then((result) => console.log(result))
.catch((error) => console.log("error", error));
Respuesta del servidor
{
"id": "5c46d97b-22d5-4917-8833-3a61385d7c27",
"name": "Producto #1",
"short_description": null,
"description": null,
"stock": 0,
"price": 55,
"currency": "USD",
"is_physical": false,
"bar_code": null,
"sku": null,
"recurrence": null,
"images": {
"images": [],
"default": ""
},
"payment_link": false,
"test": true,
"total_price": 55,
"taxes": []
}
Como notaras hay muchos mas campos que cuando se creo el producto, todos estos campos son configurables y opcionales cuando se crea el producto o cuando se actualiza
La recurrencia solo puede ser configurada cuando se crea el producto
Update a product​
PUT /v1/products/<id>/
La actualización de un producto se realiza de la siguientes maneras
Imagina el caso en el que quieras actualizar la descripción corta del producto entonces realizarÃas la siguiente consulta:
Se envÃa el nombre del campo en este caso short_description
con el valor que queremos darle, en este caso Producto dedicado a todas las edades
Puedes enviar multiples campos a la ves
- Curl
- Python
- Angular
- Javascript
curl --location --request PUT 'https://api.4geeks.io/v1/products/5c46d97b-22d5-4917-8833-3a61385d7c27/' \
--form 'short_description="Producto dedicado a todas las edades"'
import requests
url = "https://api.4geeks.io/v1/products/5c46d97b-22d5-4917-8833-3a61385d7c27/"
payload={'short_description': 'Producto dedicado a todas las edades'}
files=[
]
headers = {}
response = requests.request("PUT", url, headers=headers, data=payload, files=files)
print(response.text)
import { HttpClient } from "@angular/common/http";
import { Injectable } from "@angular/core";
import { Observable } from "rxjs";
@Injectable({
providedIn: "root",
})
export class ProductService {
url = "https://api.4geeks.io/v1/products/";
constructor(private http: HttpClient) {}
updateProduct(id: String): Observable<any> {
var formdata = new FormData();
formdata.append(
"short_description",
"Producto dedicado a todas las edades"
);
return this.http.put<any>(url, formdata);
}
}
var formdata = new FormData();
formdata.append("short_description", "Producto dedicado a todas las edades");
var requestOptions = {
method: "PUT",
body: formdata,
redirect: "follow",
};
fetch(
"https://api.4geeks.io/v1/products/5c46d97b-22d5-4917-8833-3a61385d7c27/",
requestOptions
)
.then((response) => response.text())
.then((result) => console.log(result))
.catch((error) => console.log("error", error));
El servidor te retornara la siguiente respuesta y en caso de necesitarlo en el campo data
te devuelve los valores actualizados del producto
{
"code": 200,
"title": "Updated product",
"content": "The product was successfully updated.",
"type": "success",
"data": {
"id": "5c46d97b-22d5-4917-8833-3a61385d7c27",
"name": "Producto #1",
"short_description": "Producto dedicado a todas las edades",
"description": null,
"stock": 0,
"price": 55.0,
"currency": "USD",
"is_physical": false,
"bar_code": null,
"sku": null,
"recurrence": null,
"images": {
"images": [],
"default": ""
},
"payment_link": false,
"test": true,
"total_price": 55.0,
"taxes": []
}
}
Como notaras el campo short_description
se actualizo correctamente
List products​
GET /v1/products/
Para consultar la lista de productos se realiza la siguiente consulta:
- Curl
- Python
- Angular
- Javascript
curl --location 'https://api.4geeks.io/v1/products/'
import requests
url = "https://api.4geeks.io/v1/products/"
payload={}
headers = {}
response = requests.request("GET", url, headers=headers, data=payload)
import { HttpClient } from "@angular/common/http";
import { Injectable } from "@angular/core";
import { Observable } from "rxjs";
@Injectable({
providedIn: "root",
})
export class ProductService {
url = "https://api.4geeks.io/v1/products/";
constructor(private http: HttpClient) {}
listProduct(): Observable<any> {
return this.http.get<any>(`${url}`);
}
}
var requestOptions = {
method: "GET",
redirect: "follow",
};
fetch("https://api.4geeks.io/v1/", requestOptions)
.then((response) => response.text())
.then((result) => console.log(result))
.catch((error) => console.log("error", error));
Respuesta del servidor
[
{
"id": "5c46d97b-22d5-4917-8833-3a61385d7c27",
"name": "Producto #1",
"short_description": "Producto dedicado a todas las edades",
"description": null,
"stock": 0,
"price": 55,
"currency": "USD",
"is_physical": false,
"bar_code": null,
"sku": null,
"recurrence": null,
"images": {
"images": [],
"default": ""
},
"payment_link": false,
"test": true,
"total_price": 55,
"taxes": []
},
{
"id": "b9028ee4-959d-49ac-a2d0-c2b6fa6056dd",
"name": "Producto #2",
"short_description": "Producto para niños",
"description": "Pack de juguetes infantiles",
"stock": 0,
"price": 155,
"currency": "USD",
"is_physical": false,
"bar_code": null,
"sku": null,
"recurrence": null,
"images": {
"images": [],
"default": ""
},
"payment_link": false,
"test": true,
"total_price": 155,
"taxes": []
}
]