Mon site marche, mon app ne marche pas
Le même appel, les mêmes fonctions, et pourtant l'intégration passe sur le site et échoue dans l'application. Ce n'est pas un bug : c'est que l'appel n'est pas au bon endroit. Voici pourquoi, et le flux correct.
Le symptôme
Vous avez intégré MonCashConnect sur votre site et tout fonctionne. Vous reprenez le même code dans votre application Android (APK) ou dans une WebView, et l'appel à pay-create échoue, souvent sans message clair. Vous avez mis l'adresse de votre site dans les domaines autorisés, et vous cherchez comment y ajouter l'application.
Cette page existe parce que la réponse n'est pas « ajoutez l'app à la liste ».
Pourquoi ça bloque
La liste des domaines autorisés de votre projet est une règle de navigateur, le CORS. Le navigateur envoie l'origine de la page (par exemple https://monsite.com) ; si elle figure dans votre liste, la réponse porte l'en-tête qui autorise votre code à la lire. Sinon, le navigateur bloque la lecture.
Une application native n'a pas d'origine web à présenter. Le contrôle ne peut donc ni réussir ni être configuré pour elle : il n'y a rien à ajouter dans la liste.
OPTIONS) réussit depuis n'importe quelle origine. C'est la vraie requête qui est bloquée, et le navigateur interdit à votre code de lire la raison. D'où l'erreur réseau générique, sans explication.Le vrai risque : la clé secrète
pay-create elle-même, c'est que votre clé sk_proj_… est à l'intérieur de l'APK. Un APK est une archive : n'importe qui peut la décompresser et lire la clé, puis créer des paiements sur votre compte. Le problème de CORS vous a en réalité protégé d'une erreur plus grave.La clé secrète ne doit exister que sur un serveur que vous contrôlez. Cela vaut aussi pour une clé sandbox : même architecture en test et en production.
Le flux correct
App mobile Votre serveur MonCashConnect
│ │ │
│ POST /api/create-payment │ │
├──────────────────────────>│ │
│ │ POST /v1/pay-create │
│ │ Authorization: sk_proj_ │
│ ├──────────────────────────>│
│ │<── paymentUrl, reference ─┤
│<──────── paymentUrl ──────┤ │
│ │ │
│ ouvre le paymentUrl (navigateur ou WebView) │
│ le client paie sur MonCash │
│ retour vers votre returnUrl (deep link possible) │
│ │<──── webhook signé ───────┤
│ lit le statut auprès de votre serveur │Côté serveur, l'appel est exactement celui de la documentation :
curl -X POST https://api.moncashconnect.com/v1/pay-create \
-H "Authorization: Bearer sk_proj_xxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"amount": 500,
"referenceId": "commande-1043",
"returnUrl": "https://monsite.com/merci"
}'Pour le code complet côté application, suivez le guide de votre plateforme : React Native ou Flutter. Les deux montrent l'ouverture du paymentUrl, le retour par deep link et la vérification du webhook.
Cas particulier : une WebView qui charge votre site
Si votre APK n'est qu'une WebView autour de votre site déjà en ligne, la règle ne change pas : l'appel doit rester côté serveur. En revanche deux points méritent attention.
- L'origine envoyée par la WebView peut différer de celle de votre site (elle peut être absente, ou
file://si vous chargez des fichiers locaux). Si votre page appelle votre propre backend, cela ne vous concerne plus : c'est votre serveur qui parle à MonCashConnect. - Le retour de paiement doit rester dans l'application. Donnez un
returnUrlque votre WebView sait intercepter, ou une page de votre site qui referme proprement le parcours. Sans cela le client termine son paiement dans un navigateur externe et ne revient jamais dans l'app.
Checklist
Aucune clé sk_proj_ ni sk_test_proj_ dans le code de l'application
L'application appelle votre backend, jamais api.moncashconnect.com directement
Votre backend détient la clé secrète et appelle pay-create
Le paymentUrl est renvoyé à l'application, qui l'ouvre
Le returnUrl ramène le client dans l'application (deep link ou page de retour)
La confirmation vient du webhook signé, ou de pay-status appelé par votre serveur
Les domaines autorisés ne contiennent que vos adresses web réelles