Cotes, paris et coupons — documentation technique de l’API
Ce fichier contient un script autonome minimal pour la connexion au système de calcul de coupons SportAPI. Les détails et les cas rares se trouvent dans la documentation complète.
POST /api/partner/login
POST /api/partner/coupons/place
GET /api/partner/coupons/calculated?time=10 1. Ce que vous devez obtenir du gestionnaire
- API d’URL de base ;
- identifiant et mot de passe du compte client ;
- lors de l’utilisation du rappel - activez la fonction et la phrase secrète
callback_secret.
Les exemples utilisent une adresse conditionnelle :
BASE_URL="https://coupon-api.example.com"
En production, utilisez HTTPS. Toutes les dates sont transmises sous forme d’horodatage Unix en millisecondes et les valeurs monétaires sont transmises sous forme de nombres décimaux sans précision fixe.
2. Format de réponse API
Succès :
{
"code": 1,
"body": {},
"error_code": null,
"error_message": null,
"date": 1784970000000,
"time_ms": 5,
"path": "/api/partner/example"
}
L’erreur commerciale est généralement également accompagnée du HTTP 200 :
{
"code": 0,
"body": null,
"error_code": 1002,
"error_message": "Not all params",
"date": 1784970000000,
"time_ms": 5,
"path": "/api/partner/example"
}
Vérifiez toujours le code HTTP, puis code, puis error_code. N’utilisez pas le texte error_message comme clé logicielle.
3. Autorisation
POST /api/partner/login
Content-Type: application/json
{
"username": "partner-demo",
"password": "strong-password"
}
Le champ login est pris en charge en tant qu’alias compatible username.
Réponse réussie :
{
"code": 1,
"body": {
"token": "<jwt-token>",
"user_id": 17,
"username": "partner-demo"
},
"error_code": null,
"error_message": null
}
Dans toutes les requêtes protégées, transmettez :
Authorization: Bearer <jwt-token>
Erreurs de connexion de base :
| Coder | Raison |
|---|---|
1002 | Login ou mot de passe non envoyé. |
1003 | Identifiant inconnu ou mot de passe incorrect. |
1004 | Le compte client a été désactivé. |
1006 | La date d’accès a expiré. |
1007 | Le solde du client est nul ou négatif. |
Ces erreurs sont renvoyées par HTTP 200, code = 0. HTTP 401 d’une méthode protégée signifie que le JWT est manquant, invalide, expiré ou révoqué ; Connectez-vous à nouveau. HTTP 403 signifie un rôle inapproprié ou un accès refusé.
4. Indicateur de taux
Chaque résultat sélectionné est transmis sous forme de ligne prête à l’emploi à partir de la ligne sportive :
line_type#game_id#group_id#type_id#rate#coefficient[#player_id]
Exemples :
line#737779544#1#1#0#1.85
live#738917381|119|5869|0.5#3.6#149439538
line_type:lineoulive;rate: paramètre total/handicap ou0;player_id: ID de joueur en option ;- les délimiteurs
#et|sont pris en charge.
Ne collectez pas et ne corrigez pas le pointeur manuellement - transmettez la valeur obtenue à partir de la ligne inchangée.
5. Créer un coupon
POST /api/partner/coupons/place
Authorization: Bearer <jwt-token>
Content-Type: application/json
{
"list_bets": [
"line#737779544#1#1#0#1.85"
],
"amount": 10,
"currency": "USD",
"callback_url": "https://partner.example.com/api/coupon-result",
"lang": "en",
"mode": "reject",
"mode_type": null,
"multi": false
}
| Champ | Obligatoire | Objectif |
|---|---|---|
list_bets | Oui | Un ou plusieurs pointeurs. |
amount | Oui | Le montant positif d’un coupon en cours de création. |
currency | Non | Toute désignation de chaîne, y compris la monnaie virtuelle. |
callback_url | Non | Rappel d’URL ; sans rappel, vous ne pouvez pas l’envoyer, vous pouvez transmettre null, une chaîne vide ou un domaine de site. |
lang | Non | Un code à deux lettres pour l’une des 50 langues environ prises en charge. Le langage des noms est fixé lors de la création. |
mode | Non | reject ou accept ; par défaut reject. |
mode_type | Pour accept | Direction admissible du changement de coefficient. |
multi | Non | Un coupon général ou individuel simple ; par défaut false. |
Chances
| Paramètres | Comportement |
|---|---|
mode = reject | Rejeter la création lorsque le coefficient change. |
mode = accept, mode_type = 1 | Acceptez uniquement les promotions. |
mode = accept, mode_type = 2 | Acceptez uniquement la rétrogradation. |
mode = accept, mode_type = 3 | Acceptez tout changement. |
Ordinaire, express et multi
| Demande | Résultat | Radiation du solde du client |
|---|---|---|
| Un résultat | Un ordinaire | amount |
Résultats multiples, multi = false | Un express | amount |
Résultats multiples, multi = true | Séparé unique pour chaque résultat | amount × nombre de coupons créés |
Un train express ne peut contenir plus de 15 événements. Vous ne pouvez pas combiner plusieurs paris sur le même match, y compris le match principal, les mi-temps, les périodes, les corners, les fautes et autres sous-événements associés. Cette combinaison renvoie 506.
6. Confirmation du coupon et création de l'offre
Réponse complète réussie avec coupon et données de pari acceptés dans events_data :
{
"code": 1,
"body": {
"coupons": [
{
"coupon_code": "000000000272",
"amount": 10,
"win": 18.5,
"potential_win": 18.5,
"real_win": null,
"coef": 1.85,
"original_coef": 1.85,
"calculate_coef": null,
"has_return": false,
"date": 1784970000000,
"status": 0,
"asian": false,
"calculate_date": null,
"coupon_type": 1,
"events_count": 1,
"events_data": [
{
"id": 912,
"game_id": 737779544,
"main_game_id": 737779544,
"is_sub_game": false,
"parent_game_id": null,
"sub_game_key": null,
"raw_pointer": "line#737779544#1#1#0#1.85",
"line_type": "line",
"is_live": false,
"bet_group_id": 1,
"bet_group_name": "Match result",
"bet_id": 1,
"bet_name": "First team to win",
"sport_id": 1,
"sport_name": "Football",
"tournament_id": 10001,
"tournament": "National League",
"event_date": 1784971800000,
"status": 0,
"opp1": "Team A",
"opp2": "Team B",
"coef": 1.85,
"calc_coef": null,
"bet_score": "line#737779544#1#1#0#1.85",
"calculate_date": null,
"calculate_score": null,
"settlement_reason_code": null,
"settlement_reason": null,
"placement_score_full": null,
"placement_score_periods": null,
"calculation_score_full": null,
"calculation_score_periods": null,
"timer": null,
"dop_name": null,
"rate": "0",
"sgame_id": null,
"game_num": null,
"stat_id": null,
"team1_id": 101,
"team2_id": 102,
"opp_icon1": 101,
"opp_icon2": 102
}
]
}
]
},
"error_code": null,
"error_message": null,
"date": 1784970000015,
"time_ms": 45,
"path": "/api/partner/coupons/place"
}
Champs de coupons
Chaque article body.coupons[] est un coupon distinct créé.
| Champ | Tapez | Signification |
|---|---|---|
coupon_code | string | Code promo public à 12 chiffres. Stockez sous forme de chaîne pour éviter de perdre les zéros non significatifs. |
amount | number | Le montant du coupon transféré lors de la création. |
win | number | Montant gagnant actuellement affiché. |
potential_win | number | Gains possibles avant règlement définitif. |
real_win | number/null | Montant réel du paiement après calcul ; avant calcul - null. |
coef | number | Ratio du coupon actuel ou final. |
original_coef | number | Le coefficient total du coupon au moment de sa création. |
calculate_coef | number/null | Coefficient calculé final ; avant calcul - null. |
has_return | boolean | true, si le coupon contient un pari avec un statut de remboursement. |
date | integer | Date de création du coupon, horodatage Unix en millisecondes. |
status | integer | Statut actuel du coupon. Les valeurs sont décrites dans la section « Statut du coupon et de l’enchère ». |
asian | boolean | Signe de la présence d’un règlement asiatique, comprenant la moitié des gains ou des pertes. |
calculate_date | integer/null | Date de calcul du coupon en millisecondes ; avant calcul - null. |
coupon_type | integer | Type de coupon : 1 - ordinaire, 2 - express. |
events_count | integer | Nombre de paris à l’intérieur du coupon. |
events_data | array | La gamme complète de paris inclus dans le coupon. |
Champs d’enchères
Chaque élément de events_data[] décrit un pari spécifique accepté dans le coupon.
| Champ | Tapez | Signification |
|---|---|---|
id | integer/null | ID interne du pari accepté. Utilisé conjointement avec coupon_code pour rechercher un tarif dans un coupon. |
game_id | integer | ID de l’événement ou du sous-événement sur lequel le pari est placé. |
main_game_id | integer/null | ID du match principal auquel appartient l’événement ou le sous-événement. |
is_sub_game | boolean | true, si le pari concerne une mi-temps, une période, un set, des corners ou tout autre sous-événement. |
parent_game_id | integer/null | L’ID de l’événement parent immédiat, s’il existe. |
sub_game_key | string/null | Clé technique d’un sous-événement ou d’une période. |
raw_pointer | string | L’indicateur de taux d’origine accepté par l’API. |
line_type | string | Type de ligne : line - pré-match, live - événement en temps réel. |
is_live | boolean | true, si le pari a été créé sur une ligne en direct. |
bet_group_id | integer | ID du groupe de paris ou du marché. |
bet_group_name | string/null | Nom localisé du groupe de pari. |
bet_id | integer | ID de la sélection sélectionnée au sein du groupe de paris. |
bet_name | string/null | Nom complet localisé de la sélection sélectionnée. |
sport_id | integer/null | Carte d’identité sportive. |
sport_name | string/null | Nom localisé du sport. |
tournament_id | integer/null | Identifiant du tournoi. |
tournament | string/null | Nom localisé du tournoi. |
event_date | integer/null | Date de début de l’événement, horodatage Unix en millisecondes. |
status | integer | État actuel du calcul du taux. A ne pas confondre avec le statut du coupon. |
opp1 | string/null | Nom de la première équipe ou participant. |
opp2 | string/null | Nom de la deuxième équipe ou participant. |
coef | number | La cote du pari à laquelle le pari a été accepté. |
calc_coef | number/null | Multiplicateur de pari calculé ; avant calcul - null. |
bet_score | string | Champ compatible avec l’API héritée contenant l’indicateur de pari plutôt que le score du match. |
calculate_date | integer/null | Date de calcul du taux en millisecondes ; avant calcul - null. |
calculate_score | string/null | Le compte utilisé pour calculer le pari. |
settlement_reason_code | string/null | Code machine stable du motif du paiement ou du retour ; avant calcul - null. |
settlement_reason | string/null | Texte explicatif du motif du paiement ou du retour ; avant calcul - null. |
placement_score_full | string/null | Score total de l’événement au moment de la création du pari, si disponible. |
placement_score_periods | string/null | Score par période au moment de la création du pari, si disponible. |
calculation_score_full | string/null | Le score total de l’événement au moment où le pari est réglé. |
calculation_score_periods | string/null | Compte par période au moment du calcul du taux. |
timer | integer/null | Minuterie d’événement au moment de la sauvegarde des données, si disponible. |
dop_name | string/null | Nom du sous-événement : mi-temps, période, set, manche, etc. |
rate | string | Paramètre de résultat, par exemple la valeur du total ou du handicap ; pour un résultat sans paramètre - "0". |
sgame_id | string/null | Clé étrangère de sous-événement. |
game_num | integer/null | Numéro de jeu, si fourni par la source. |
stat_id | string/null | ID d’événement statistique externe. |
team1_id | integer/null | ID de la première équipe ou participant. |
team2_id | integer/null | ID de la deuxième équipe ou participant. |
opp_icon1 | integer/null | ID compatible de la première icône de commande ; correspond à team1_id. |
opp_icon2 | integer/null | ID d’icône de deuxième équipe compatible ; correspond à team2_id. |
La valeur null est normale pour les données qui n’ont pas encore été calculées ou qui ne sont pas disponibles. Ne le remplacez pas automatiquement par 0 ou la chaîne vide.
Considérez le coupon accepté uniquement si code = 1 et la présence d’objets dans body.coupons. Avant cela, le panier est un choix préliminaire : la sélection peut disparaître, être bloquée ou les cotes changer.
Après succès :
- enregistrez tous les objets
body.coupons, pas seulement le premier ; - stocker
coupon_codesous forme de chaîne avec des zéros non significatifs ; - enregistrez les données requises à partir de
events_data; - faire correspondre le coupon à l’utilisateur final ;
- enregistrer la transaction financière de l’utilisateur dans le système du partenaire.
Identifiants :
| Champ | Objectif |
|---|---|
coupon_code | Code de réduction public. |
events_data[].id | ID du pari spécifique accepté à l’intérieur du coupon. |
rappel events_data[].uuid | Le même identifiant d’enchère, transmis sous forme de chaîne. |
batchId | ID de la version du package de rappel, pas du coupon ou du tarif. |
currency n’est pas renvoyé dans le modèle complet et le rappel. Si la devise est nécessaire, enregistrez la valeur de la demande de création.
7. Erreurs de création
| Coder | Raison | Action |
|---|---|---|
10 | Aucun corps de requête. | Corrigez la demande. |
11 | Pointeur invalide. | Obtenez le pointeur actuel de la ligne. |
12 | amount non valide. | Passez un nombre positif. |
501 | Le coefficient a changé. | Afficher une nouvelle valeur ou modifier mode. |
502 | Il n’y a pas de résultat. | Supprimer/mettre à jour l’enchère dans le panier. |
503 | Le résultat est bloqué. | Signaler une indisponibilité temporaire. |
504 | Erreur de vérification du résultat. | Ne considérez pas le coupon comme accepté ; répéter plus tard. |
506 | Dans les paris express, un match. | Laissez un résultat ou utilisez des singles séparés. |
507 | Solde client insuffisant. | Rechargez votre solde ou réduisez le montant total. |
1002 | Jeu de paramètres invalide. | Paramètres corrects. |
10000 | Erreur interne. | Enregistrez l’erreur et vérifiez le résultat avant de réessayer. |
Pour 501 à 504, la nouvelle API renvoie les taux problématiques dans body.changes[]. Champ change_type : 1 - le coefficient a augmenté, 2 - a diminué, null - la direction n’est pas applicable.
Ne réessayez pas aveuglément POST /coupons/place après l’expiration du délai : la première demande a peut-être été acceptée et une nouvelle tentative créera un doublon.
8. Réception de coupons
| Fonctionnement | Point de terminaison | Résultat |
|---|---|---|
| Un coupon | GET /api/partner/coupons/get?coupon_code={code} | Coupon à body. |
| Actif | GET /api/partner/coupons/active | Tableau dans body[]. |
| Calculs récents | GET /api/partner/coupons/calculated?time=10 | Tableau dans body[] ; maximum 120 minutes. |
| Par code/période | POST /api/partner/coupons/results | Tableau dans body.coupons. |
| Solde client | GET /api/partner/balance | body.balance. |
Vous pouvez transférer jusqu’à 100 valeurs à l’aide de codes :
{
"coupon_ids": ["000000000272", "000000000273"]
}
Ou ne dépassez pas la période de création de 24 heures :
{
"start_date": 1784880000000,
"end_date": 1784966400000
}
Ne combinez pas coupon_ids et les dates dans la même requête. results filtre par heure de création et calculated filtre par heure de règlement final.
9. Statuts des coupons et des paris
Statuts des coupons :
| Coder | Signification | Finale |
|---|---|---|
0 | Actif ou partiellement réglé. | Non |
2 | Gagné. | Oui |
4 | Perdu. | Oui |
8 | Entièrement remboursé. | Oui |
15 | Renvoyé pour recalcul ; attendez-vous à un nouveau résultat. | Non |
Statuts des offres :
| Coder | Signification | calc_coef |
|---|---|---|
0 | Non calculé. | null |
1 | Gagner. | Coefficient d’origine |
2 | Perdre. | 0 |
3 | Retour. | 1 |
4 | En attente de recalcul. | null |
21 | La moitié des gains. | (coef + 1) / 2 |
22 | Demi-perte. | 0.5 |
23 | Poussez. | 1 |
Pour l’accumulation financière pour l’utilisateur final, utilisez le real_win prêt à l’emploi. N’utilisez pas potential_win et ne recalculez pas le paiement vous-même. Avant le calcul, real_win, calculate_coef, calc_coef et calculate_date sont égaux à null, et non à 0.
Au premier statut du coupon 15, si le résultat précédent a déjà été traité financièrement, le partenaire débite à nouveau le amount à l’utilisateur final, attend un nouveau statut final et facture un nouveau real_win. Protéger les opérations du retraitement.
10. Raison du calcul
Chaque pari dans le modèle complet et rappel a :
| Champ | Objectif |
|---|---|
settlement_reason_code | Code de motif de paiement/remboursement stable. |
settlement_reason | Texte source explicatif. |
Avant calcul, les deux champs sont égaux à null. Pour une notification localisée, utilisez un code tel que :
MATCH_POSTPONED- le match a été reporté ;MATCH_CANCELLED- match annulé ;MARKET_PUSH- retour selon les règles du marché.
Si le code est inconnu, enregistrez-le et utilisez le settlement_reason non vide comme texte de secours. Ne calculez pas le paiement par motif - utilisez les statuts et real_win.
Ces champs expliquent le calcul ou le retour qui a déjà été effectué et ne constituent pas un flux distinct en temps réel de l’état de la correspondance.
11. Rappel
Le rappel est facultatif. Un partenaire ne peut travailler que par sondage. Pour le rappel, le gestionnaire doit activer la fonction et créer callback_secret ; L’URL est envoyée dans chaque coupon créé.
Le partenaire détermine indépendamment l’URL de rappel. En production, il doit utiliser https:// ; dans un environnement de test, http:// est autorisé.
Le système envoie :
POST {callback_url}
Content-Type: application/json
X-Coupon-Signature: sha256=<hex_hmac_sha256>
Charge utile courte :
{
"event": "coupons.settled",
"batchId": "d407e986f3a64d9d36a77bf532322ef8",
"couponCount": 1,
"coupons": [
{
"coupon_code": "000000000272",
"realWin": 18.5,
"calculate_coefficient": 1.85,
"status": 2,
"calculate_date": 1784973600000,
"events_data": [
{
"uuid": "912",
"status": 1,
"calculate_coefficient": 1.85,
"calculate_date": 1784973600000,
"calculate_score": "2:1",
"settlement_reason_code": "REMOTE_WIN",
"settlement_reason": "Win",
"timer": 0
}
]
}
]
}
Règles obligatoires :
- calculer
sha256=<hex(HMAC-SHA256(raw_body, callback_secret))>à partir des octets sources exacts du corps avant l’analyse JSON et comparer les signatures de manière sécurisée ; - traiter tous les articles
coupons, le colis peut contenir jusqu’à 100 coupons ; - stocker
batchIdavec un index unique ; - le
batchIdrépété ne doit pas répéter la radiation ou l’accumulation ; - un
coupon_codepeut être accompagné de différentsbatchIdlors du calcul et du recalcul progressifs ; - renvoie HTTP
200uniquement une fois que l’intégralité du paquet a été stockée en toute sécurité.
La réponse réussie minimale est un HTTP 200 vide. Avancé :
{
"success": true,
"processed": 1
}
processed doit être égal à couponCount. Les réponses 201, 202 et 204 ne sont pas considérées comme réussies.
Les replays sont effectués uniquement en cas de timeout, d’erreur de transport ou HTTP 500, 502, 503, 504 : immédiatement, puis après 1, 5, 15 et 60 minutes - pas plus de cinq envois. Il n’y a pas de nouvelle tentative automatique sur HTTP 200 avec success: false ou processed partielle.
12. Sondage de réserve
Même avec rappel, vérifiez périodiquement les résultats :
GET /api/partner/coupons/calculated?time=10
Après une pause de plus de 120 minutes, utilisez POST /api/partner/coupons/results sur le coupon_ids enregistré ou sur des périodes de création allant jusqu’à 24 heures. Recevoir la même fortune ne doit pas répéter les transactions financières.
13. Sécurité et stockage
- stocker le login, le mot de passe, JWT et
callback_secretuniquement sur le serveur ; - ne transmettez pas JWT dans l’URL et n’écrivez pas le jeton complet dans les journaux ;
- utilisez le type décimal pour l’argent ;
- stocker
coupon_codesous forme de chaîne ; - enregistrer
amount, les données d’offre requises etcurrency, le cas échéant ; - faire la distinction entre les statuts du coupon et de l’enchère ;
- accepter les champs inconnus et les codes de raison sans erreur ;
- Rendre idempotentes toutes les transactions financières des utilisateurs finaux.
14. Ancienne API et retrait
Les anciennes routes continuent d’être prises en charge, mais les nouvelles intégrations doivent utiliser /api/partner/**. Les anciennes réponses et erreurs ont des formats différents. Pour mettre à jour un client existant, utilisez un seul fichier « Migration depuis l’ancienne API ».
Cashout est en cours de développement, n’est pas entièrement testé et n’est pas recommandé pour la production.
15. Liste de contrôle finale
- Reçu
BASE_URL, login et mot de passe. - JWT est transmis sous forme de jeton Bearer.
- Les pointeurs sont repris de la ligne sans modification.
- Le panier n’est enregistré en tant que coupon accepté qu’après
code = 1. multitraité, restrictions expresses et erreurs501–507.- L’annulation automatique du solde client a été prise en compte.
- Tous les
coupon_codeet les identifiants d’enchères sont enregistrés. - Le paiement final provient de
real_win. - Le rappel est vérifié par rapport aux octets sources et dédupliqué à l’aide de
batchId. - L’interrogation de sauvegarde a été configurée.
- Le solde utilisateur est distinct du solde client SportAPI.
La documentation détaillée commence par Présentation de l’API. La carte complète des points de terminaison se trouve dans manuel.