Référence de l'API
Tarifs
Définissez le prix d'un produit et sa fréquence de renouvellement.
Un tarif définit combien coûte un produit et à quelle fréquence il se renouvelle. Un produit peut avoir plusieurs tarifs, comme un mensuel et un annuel.
L'objet price
Attributs
idstringIdentifiant unique du tarif.product_idstringLe produit auquel appartient le tarif.namestringLe nom du tarif, comme Monthly.currencystringXAF.amountintegerCe que le client paie à chaque période de facturation, dans la plus petite unité de la devise.intervalstringL'unité d'une période de facturation :day,week,monthouyear.interval_countintegerCombien d'intervalles composent une période de facturation.monthavec3facture tous les trois mois.created_attimestampQuand le tarif a été créé, en secondes Unix.archived_attimestampnullableQuand le tarif a été archivé. Un tarif archivé ne démarre aucun nouvel abonnement.pending_changeobjectnullableLe changement de montant programmé pour le tarif, ou null quand il n'y en a pas. Un tarif en a au plus un.Afficher les attributsMasquer les attributs
idstringIdentifiant unique du changement. Les événements de changement de tarif le portent comme price_change_id.amountintegerLe nouveau montant, dans la plus petite unité de la devise.previous_amountintegerLe montant avant le changement.currencystringLa devise du tarif,XAF.effective_attimestampMinuit au début du jour à partir duquel le nouveau montant s'applique, dans timezone.timezonestringLe fuseau horaire de votre application, commeAfrica/Douala, le même que letimezonede l'application.effective_atest minuit dans ce fuseau.keep_current_subscribersbooleantruequand toutes les personnes abonnées ce jour-là gardent l'ancien montant.created_attimestampQuand le changement a été programmé, en secondes Unix.
{
"id": "Zt6YbN3q",
"product_id": "pR4dWx9K",
"name": "Monthly",
"currency": "XAF",
"amount": 5000,
"interval": "month",
"interval_count": 1,
"created_at": 1727600000,
"archived_at": null,
"pending_change": null
}Créer un tarif
POST/v1/apps/{appID}/prices
Accepte un en-tête Idempotency-Key.
Crée un tarif pour l'un des produits de l'application.
Paramètres
product_idstringobligatoireLe produit à tarifer.namestringobligatoireLe nom du tarif, comme Monthly.currencystringobligatoireXAF. Les minuscules fonctionnent aussi.amountintegerobligatoireCe que le client paie à chaque période de facturation, dans la plus petite unité de la devise. Doit être supérieur à 0.intervalstringobligatoireday,week,monthouyear.interval_countintegerCombien d'intervalles composent une période de facturation. Par défaut1. Au plus 365 jours, 52 semaines, 12 mois ou 1 an.
Renvoie le tarif avec le statut 201. Un champ invalide renvoie 422 avec le code invalid. Si l'application n'a aucun produit avec ce product_id, renvoie 404 avec le code not_found.
curl https://api.abuna.app/v1/apps/8ddhXCDW/prices \
-H "Authorization: Bearer sk_test_..." \
-H "Content-Type: application/json" \
-d '{"product_id": "pR4dWx9K", "name": "Monthly", "currency": "XAF", "amount": 5000, "interval": "month"}'{
"id": "Zt6YbN3q",
"product_id": "pR4dWx9K",
"name": "Monthly",
"currency": "XAF",
"amount": 5000,
"interval": "month",
"interval_count": 1,
"created_at": 1727600000,
"archived_at": null,
"pending_change": null
}Lister les tarifs
GET/v1/apps/{appID}/prices
Liste les tarifs de l'application, tous produits confondus et archivés compris, du plus récent au plus ancien, une page à la fois.
Paramètres de requête
limitintegerCombien de tarifs renvoyer, de 1 à 100. Par défaut : 50.cursorstringLa valeurnext_cursorde la page précédente. Envoyez les mêmes filtres avec.
Renvoie items et next_cursor, comme décrit dans Listes et filtres. Une valeur non autorisée, comme un limit supérieur à 100, renvoie 422 avec le code invalid et le nom du paramètre dans errors.
curl https://api.abuna.app/v1/apps/8ddhXCDW/prices \
-H "Authorization: Bearer sk_test_..."{
"items": [
{
"id": "Zt6YbN3q",
"product_id": "pR4dWx9K",
"name": "Monthly",
"currency": "XAF",
"amount": 5000,
"interval": "month",
"interval_count": 1,
"created_at": 1727600000,
"archived_at": null,
"pending_change": null
}
],
"next_cursor": null
}Mettre à jour un tarif
PATCH/v1/apps/{appID}/prices/{id}
Renomme le tarif. Son montant, sa devise, sa période de facturation et son lien de paiement restent les mêmes. Pour changer ce que paient les clients, programmez un changement de tarif.
Paramètres
namestringobligatoireLe nouveau nom, comme Monthly plan.
Renvoie le tarif. Un nom vide renvoie 422 avec le code invalid. Si l'application n'a aucun tarif avec cet ID, renvoie 404 avec le code not_found.
curl https://api.abuna.app/v1/apps/8ddhXCDW/prices/Zt6YbN3q \
-X PATCH \
-H "Authorization: Bearer sk_test_..." \
-H "Content-Type: application/json" \
-d '{"name": "Monthly plan"}'{
"id": "Zt6YbN3q",
"product_id": "pR4dWx9K",
"name": "Monthly plan",
"currency": "XAF",
"amount": 5000,
"interval": "month",
"interval_count": 1,
"created_at": 1727600000,
"archived_at": null,
"pending_change": null
}Archiver un tarif
POST/v1/apps/{appID}/prices/{id}/archive
Accepte un en-tête Idempotency-Key.
Archive le tarif. Il ne démarre aucun nouvel abonnement, et les abonnements déjà dessus continuent de se renouveler. Archiver un tarif déjà archivé ne change rien. Pour l'annuler, désarchivez le tarif.
Renvoie le tarif. Si l'application n'a aucun tarif avec cet ID, renvoie 404 avec le code not_found.
curl https://api.abuna.app/v1/apps/8ddhXCDW/prices/Zt6YbN3q/archive \
-X POST \
-H "Authorization: Bearer sk_test_..."{
"id": "Zt6YbN3q",
"product_id": "pR4dWx9K",
"name": "Monthly",
"currency": "XAF",
"amount": 5000,
"interval": "month",
"interval_count": 1,
"created_at": 1727600000,
"archived_at": 1727686400,
"pending_change": null
}Désarchiver un tarif
POST/v1/apps/{appID}/prices/{id}/unarchive
Accepte un en-tête Idempotency-Key.
Désarchive le tarif. Il peut de nouveau démarrer de nouveaux abonnements, et son lien de paiement fonctionne de nouveau. Désarchiver un tarif qui n'est pas archivé ne change rien.
Renvoie le tarif. Si l'application n'a aucun tarif avec cet ID, renvoie 404 avec le code not_found.
curl https://api.abuna.app/v1/apps/8ddhXCDW/prices/Zt6YbN3q/unarchive \
-X POST \
-H "Authorization: Bearer sk_test_..."{
"id": "Zt6YbN3q",
"product_id": "pR4dWx9K",
"name": "Monthly",
"currency": "XAF",
"amount": 5000,
"interval": "month",
"interval_count": 1,
"created_at": 1727600000,
"archived_at": null,
"pending_change": null
}Programmer un changement de tarif
POST/v1/apps/{appID}/prices/{id}/change
Accepte un en-tête Idempotency-Key.
Programme un nouveau montant pour le tarif, à partir d'un jour situé au moins 14 jours plus loin. Le montant ne change jamais tout de suite. La devise et la période de facturation ne peuvent pas changer. Pour une autre, créez un nouveau tarif.
À partir du début de ce jour dans le fuseau horaire de votre application, les paiements et les nouveaux abonnements paient le nouveau montant. Chaque abonné en cours le paie à partir de son premier renouvellement à cette date ou après. Abuna leur envoie tous un e-mail maintenant avec le nouveau montant et la date à laquelle il s'applique pour la première fois, et leur envoie un message sur Telegram s'ils l'ont connecté. Les clients qui s'abonnent pendant que le changement est en attente reçoivent le même avis au moment de s'abonner.
Avec keep_current_subscribers, toutes les personnes abonnées ce jour-là continuent de payer l'ancien montant tant qu'elles restent abonnées, et seuls les abonnés suivants paient le nouveau. Un abonné qui passe à un autre tarif puis revient paie le montant du tarif à ce moment-là.
Un tarif a un seul changement en attente. En programmer un autre le remplace. Si le remplacement garde les abonnés en cours sur l'ancien montant, ceux qui ont été informés du changement précédent reçoivent un e-mail disant que leur tarif reste. Abuna enregistre un price_change.scheduled événement, et price_change.applied quand le nouveau montant démarre.
Paramètres
amountintegerobligatoireLe nouveau montant, dans la plus petite unité de la devise. Doit être supérieur à 0 et différent du montant actuel.effective_attimestampobligatoireN'importe quelle heure du jour où le nouveau montant démarre, en secondes Unix. Abuna la ramène au début de ce jour dans le fuseau horaire de votre application. Ce jour doit être au moins 14 jours après aujourd'hui dans ce fuseau.keep_current_subscribersbooleanGarder toutes les personnes abonnées ce jour-là sur l'ancien montant. Par défautfalse.
Renvoie le tarif avec pending_change défini. Une vérification échouée renvoie 422 avec le code invalid, et chaque élément errors nomme le champ : amount avec invalid ou unchanged, ou effective_at avec required ou too_soon. Tout autre champ, comme currency ou interval, renvoie 400 avec le code invalid_json. Si l'application n'a aucun tarif avec cet ID, renvoie 404 avec le code not_found. Une fois que le changement en attente atteint son effective_at, il ne peut plus être remplacé avant d'être appliqué, et la requête renvoie 409 avec le code change_in_effect. Voir Quand le changement prend effet.
curl https://api.abuna.app/v1/apps/8ddhXCDW/prices/Zt6YbN3q/change \
-X POST \
-H "Authorization: Bearer sk_test_..." \
-H "Content-Type: application/json" \
-d '{"amount": 6000, "effective_at": 1730458800, "keep_current_subscribers": false}'{
"id": "Zt6YbN3q",
"product_id": "pR4dWx9K",
"name": "Monthly",
"currency": "XAF",
"amount": 5000,
"interval": "month",
"interval_count": 1,
"created_at": 1727600000,
"archived_at": null,
"pending_change": {
"id": "W4hN7gPc",
"amount": 6000,
"previous_amount": 5000,
"currency": "XAF",
"effective_at": 1730415600,
"timezone": "Africa/Douala",
"keep_current_subscribers": false,
"created_at": 1727700000
}
}Annuler un changement de tarif
POST/v1/apps/{appID}/prices/{id}/change/cancel
Accepte un en-tête Idempotency-Key.
Annule le changement en attente du tarif, donc le montant reste tel quel. Si des abonnés en cours devaient passer au nouveau montant, Abuna leur envoie un e-mail disant que leur tarif reste. Abuna enregistre un price_change.canceled événement.
Renvoie le tarif avec pending_change à null. Si l'application n'a aucun tarif avec cet ID, renvoie 404 avec le code not_found. Sans changement en attente, renvoie 409 avec le code no_pending_change. Une fois que le changement atteint son effective_at, il ne peut plus être annulé, et la requête renvoie 409 avec le code change_in_effect.
curl https://api.abuna.app/v1/apps/8ddhXCDW/prices/Zt6YbN3q/change/cancel \
-X POST \
-H "Authorization: Bearer sk_test_..."{
"id": "Zt6YbN3q",
"product_id": "pR4dWx9K",
"name": "Monthly",
"currency": "XAF",
"amount": 5000,
"interval": "month",
"interval_count": 1,
"created_at": 1727600000,
"archived_at": null,
"pending_change": null
}Quand le changement prend effet
Un changement prend effet à son effective_at, et Abuna enregistre price_change.applied dans la minute environ qui suit. Entre-temps, pending_change montre encore le changement, et l'annuler ou le remplacer renvoie 409 avec le code change_in_effect. Une fois price_change.applied enregistré, pending_change est null et vous pouvez programmer un nouveau changement.