---
## Chimoney সম্পর্কে
[Chimoney](https://chimoney.io/) একটি বৈশ্বিক পেমেন্ট অবকাঠামো প্রদানকারী, যা ব্যবসা, প্রতিষ্ঠান এবং কমিউনিটিকে 130+ দেশে তাত্ক্ষণিকভাবে বাল্ক পেমেন্ট পাঠাতে সক্ষম করে।
পেমেন্টগুলি ব্যাংক ট্রান্সফার, মোবাইল মানি, গিফট কার্ড এবং এয়ারটাইমের মাধ্যমে রিডিম করা যায়।
## Chimoney API সম্পর্কে
[Chimoney API](https://chimoney.readme.io/reference/introduction) আপনাকে প্রোগ্রাম্যাটিকভাবে সীমান্ত পারাপারের পেমেন্ট পাঠাতে, গ্রহণ করতে এবং সংগ্রহ করতে দেয়। এটি ব্যাংক অ্যাকাউন্ট, মোবাইল মানি ওয়ালেট, গিফট কার্ড এবং এয়ারটাইমসহ একাধিক চ্যানেল সমর্থন করে।
[এই ভিডিওটি](https://www.youtube.com/watch?v=VItvZbPH9cU&t=4s) Chimoney API সম্পর্কে আরও জানতে সাহায্য করবে।
## Chimoney কমিউনিটি প্রোজেক্ট সম্পর্কে
Chimoney কমিউনিটি প্রোজেক্ট হলো ডেভেলপার, লেখক এবং কমিউনিটি সদস্যদের দ্বারা Chimoney API ব্যবহার করে তৈরি করা ওপেন সোর্স অবদান।
এতে বিভিন্ন প্রোগ্রামিং ভাষার SDK, উদাহরণ অ্যাপ্লিকেশন, ইন্টিগ্রেশন এবং বাস্তব-জগতের ব্যবহার কেস নিয়ে প্রযুক্তিগত নিবন্ধ অন্তর্ভুক্ত থাকে।
> **নোট:** Chimoney কমিউনিটি প্রোজেক্ট বিভিন্ন প্রোগ্রামিং ভাষা এবং টেক স্ট্যাক ব্যবহার করে তৈরি।
> তাই প্রতিটি প্রোজেক্টের আলাদা README ফাইলে সেটআপ নির্দেশনা দেওয়া থাকে।
> কোন প্রোজেক্ট চালানো বা অবদান রাখার আগে অবশ্যই সেই README চেক করুন।
## Chimoney API দিয়ে শুরু করা
Chimoney API ব্যবহার শুরু করতে, [sandbox.chimoney.io](https://sandbox.chimoney.io) এ একটি ডেভেলপার অ্যাকাউন্ট খুলুন।
এই [স্টেপ-বাই-স্টেপ গাইড](https://www.loom.com/share/436303eb69c44f0d9757ea0c655bed89?sid=b6a0f661-721c-4731-9873-ae6f2d25780) আপনাকে অ্যাকাউন্ট তৈরি, API Key জেনারেট এবং স্যান্ডবক্স এনভায়রনমেন্টে প্রথম টেস্ট পেমেন্ট করার প্রক্রিয়া দেখাবে।
সেটআপ সম্পন্ন হলে, আপনি Chimoney API এক্সপ্লোর করতে পারবেন, রিকোয়েস্ট পাঠাতে পারবেন এবং বাস্তব ব্যবহার কেসসহ প্রোজেক্ট তৈরি করতে পারবেন।
## অবদান রাখা
Chimoney কমিউনিটি প্রোজেক্টে ডেভেলপার, লেখক ও ডিজাইনারদের স্বাগত জানানো হয় যারা Chimoney API ব্যবহার করে তৈরি, লিখতে বা কিছু তৈরি করতে চান।
আপনি SDK, ইন্টিগ্রেশন, উদাহরণ অ্যাপ বা বাস্তব ব্যবহার কেস দেখানো টেকনিক্যাল আর্টিকেল জমা দিয়ে অবদান রাখতে পারেন।
শুরু করার জন্য এই রিপোজিটরির [ওপেন ইস্যুগুলি](https://github.com/Chimoney/chimoney-community-projects/issues) ব্রাউজ করুন অথবা আপনার নিজের আইডিয়া প্রস্তাব করুন।
অবদান জমা দিতে প্রস্তুত হলে:
1. রিপো ফর্ক করুন।
2. একটি ব্রাঞ্চ তৈরি করুন।
3. আপনার পরিবর্তনগুলি করুন।
4. একটি Pull Request খুলুন।
অবশ্যই একটি স্পষ্ট বর্ণনা দিন এবং প্রোজেক্টের ফোল্ডার স্ট্রাকচার অনুসরণ করুন; সব অবদান `submissions/` ডিরেক্টরিতে যাবে এবং নির্দিষ্ট ক্যাটাগরি অনুযায়ী সাবফোল্ডারে রাখতে হবে (যেমন আর্টিকেল `articles/` ফোল্ডারে, SDK `SDKs/` ফোল্ডারে)।
অধিক কার্যকরভাবে অবদান রাখার জন্য সম্পূর্ণ [অবদান নির্দেশিকা](/CONTRIBUTING.md) পড়ুন।
## Chimoney Hacktoberfest
Chimoney 2022 সাল থেকে প্রতি বছর [Hacktoberfest](https://hacktoberfest.com/) এ অংশ নিচ্ছে, যেখানে ডেভেলপার, লেখক ও ডিজাইনাররা আমাদের ওপেন সোর্স কমিউনিটিতে অবদান রাখেন।
প্রতি অক্টোবর, আমরা নতুন ও অভিজ্ঞ কন্ট্রিবিউটরদের জন্য সহজবোধ্য **`Hacktoberfest`** ইস্যু তৈরি করি।
Hacktoberfest চলাকালীন অর্থবহ অবদানের জন্য আমরা পুরস্কার ও স্বীকৃতিও প্রদান করি।
আমাদের আগের Hacktoberfest রিক্যাপ দেখতে, আপনি কিভাবে যুক্ত হতে পারেন এবং কিভাবে সর্বাধিক অবদান রাখতে পারেন তা জানতে, বিস্তারিত পড়ুন।
### Hacktoberfest 2025
Chimoney Hacktoberfest 2025-এ অংশ নিচ্ছে! ✨
এ বছর আমাদের বিদ্যমান ওপেন সোর্স প্রোজেক্টগুলির পাশাপাশি, আমরা একটি সম্পূর্ণ নতুন প্রোজেক্ট চালু করছি: **IaaS-k8s**
IaaS-k8s হলো একটি মাল্টি-ক্লাউড Kubernetes অবকাঠামো ডেপ্লয়মেন্ট সলিউশন, যা AWS EKS এবং GCP GKE সমর্থন করে, এবং Pulumi ও TypeScript দিয়ে তৈরি।
➝ _এখানে আরও জানুন এবং শুরু করুন:_ [_IaaS-k8s প্রোজেক্ট_](https://github.com/Chimoney/Iaas)
সবসময় যেমনটি হয়, এই রিপোতে সকল স্তরের কন্ট্রিবিউটরের জন্য ওপেন ইস্যু থাকবে।
## আমাদের কমিউনিটিতে যোগ দিন
[Discord সার্ভার](https://discord.gg/TsyKnzT4qV)-এ Chimoney API ব্যবহারকারীদের সাথে যুক্ত হন।
অংশগ্রহণের আগে দয়া করে আমাদের [কোড অফ কন্ডাক্ট](https://github.com/Chimoney/chimoney-community-projects/blob/main/CODE_OF_CONDUCT.md) পড়ুন।
## যোগাযোগ
এই রিপোজিটরি [@phyleria](https://github.com/phyleria) দ্বারা সক্রিয়ভাবে রক্ষণাবেক্ষণ করা হয়, এবং [@brijesh](https://github.com/brijeshthummar02) ও [@Daniel](https://github.com/Danbaba1) সমর্থন প্রদান করেন।
যেকোন প্রশ্ন বা সরাসরি যোগাযোগের জন্য, অনুগ্রহ করে **** ইমেইলে যোগাযোগ করুন।
================================================
FILE: README-CN.md
================================================
Pagos Globales.
Una API, acceso a más de 130 países.
[Documentación](https://chimoney.readme.io/reference/introduction) • [Kit de herramientas para desarrolladores](https://chimoney.io/toolkit/) • [Casos de uso de la API](https://chimoney.io/api-use-cases/) • [Únete a nuestro Discord](https://discord.gg/TsyKnzT4qV) • [Conéctate en X](https://x.com/chimoney_io)
---
## Acerca de Chimoney
[Chimoney](https://chimoney.io/) es un proveedor de infraestructura de pagos global que permite a empresas, organizaciones y comunidades enviar pagos masivos al instante en más de 130 países.
Los pagos pueden canjearse a través de transferencias bancarias, dinero móvil, tarjetas de regalo y recargas de tiempo aire.
## Acerca de la API de Chimoney
La [API de Chimoney](https://chimoney.readme.io/reference/introduction) te permite enviar, recibir y cobrar pagos de forma programática a través de fronteras, con soporte para múltiples canales, incluyendo cuentas bancarias, billeteras de dinero móvil, tarjetas de regalo y recargas.
[Aquí hay un video](https://www.youtube.com/watch?v=VItvZbPH9cU&t=4s) para aprender más sobre la API de Chimoney.
## Acerca de los Proyectos Comunitarios de Chimoney
Los Proyectos Comunitarios de Chimoney son contribuciones de código abierto realizadas por desarrolladores, escritores y miembros de la comunidad que usan la API de Chimoney. Incluyen SDKs en diferentes lenguajes de programación, aplicaciones de ejemplo, integraciones y artículos técnicos que muestran casos de uso en el mundo real.
> **Nota:** Los Proyectos Comunitarios de Chimoney están construidos usando diferentes lenguajes de programación y stacks tecnológicos. Como resultado, cada proyecto incluye sus propias instrucciones de configuración en su archivo README individual. Asegúrate de revisar el README específico para obtener orientación sobre cómo ejecutar o contribuir a ese proyecto.
## Primeros Pasos con la API de Chimoney
Para comenzar con la API de Chimoney, regístrate para obtener una cuenta de desarrollador en [sandbox.chimoney.io](https://sandbox.chimoney.io).
Esta [guía paso a paso](https://www.loom.com/share/436303eb69c44f0d9757ea0c655bed89?sid=b6a0f661-721c-4731-9873-ae6f2d25780) te llevará por el proceso de creación de una cuenta, generación de tu clave API y realización de tu primer pago de prueba usando el entorno sandbox.
Una vez configurado, puedes comenzar a explorar la API de Chimoney, realizar solicitudes y construir proyectos con casos de uso reales.
## Cómo Contribuir
Los Proyectos Comunitarios de Chimoney están abiertos a desarrolladores, escritores y diseñadores que quieran construir, escribir o crear alrededor de la API de Chimoney.
Puedes contribuir enviando SDKs, integraciones, aplicaciones de ejemplo o artículos técnicos que muestren casos de uso reales.
Para comenzar, explora los [issues abiertos](https://github.com/Chimoney/chimoney-community-projects/issues) en este repositorio o propone tu propia idea.
Cuando estés listo para hacer una contribución:
1. Haz un fork del repositorio.
2. Crea una rama.
3. Realiza tus cambios.
4. Abre un pull request.
Incluye una descripción clara y sigue la estructura de carpetas del proyecto; todas las contribuciones van al directorio `submissions/`, y tu aporte debe ubicarse en su subcarpeta correspondiente (ej. artículos en `articles/`, SDKs en `SDKs/`).
También puedes leer la [Guía de Contribución](/CONTRIBUTING.md) completa aquí para entender cómo contribuir de manera efectiva.
## Chimoney en Hacktoberfest
Chimoney ha participado en [Hacktoberfest](https://hacktoberfest.com/) cada año desde 2022, dando la bienvenida a desarrolladores, escritores y diseñadores para contribuir a nuestra comunidad de código abierto.
Cada octubre, creamos issues **`Hacktoberfest`** para principiantes, lo que facilita que tanto los contribuyentes nuevos como los experimentados puedan involucrarse.
También ofrecemos recompensas y reconocimiento por contribuciones significativas durante Hacktoberfest.
Para explorar nuestros resúmenes pasados, ver cómo puedes participar y aprovechar al máximo tu contribución a los proyectos de código abierto de Chimoney, lee más aquí.
### Hacktoberfest 2025
¡Chimoney está participando en Hacktoberfest 2025! ✨
Este año, junto con nuestros proyectos de código abierto existentes, estamos presentando un nuevo proyecto: **IaaS-k8s**
IaaS-k8s es una solución de despliegue de infraestructura Kubernetes multi-nube que soporta AWS EKS y GCP GKE, construida con Pulumi y TypeScript.
➝ _Conoce más sobre el proyecto y comienza aquí:_ [_Proyecto IaaS-k8s_](https://github.com/Chimoney/Iaas)
Como siempre, aún tendremos issues abiertos en este repositorio para colaboradores de todos los niveles.
## Únete a Nuestra Comunidad
Conéctate con otros que están construyendo con la API de Chimoney en nuestro [servidor de Discord](https://discord.gg/TsyKnzT4qV).
Por favor, lee nuestro [Código de Conducta](https://github.com/Chimoney/chimoney-community-projects/blob/main/CODE_OF_CONDUCT.md) antes de participar.
## Contacto
Este repositorio es mantenido activamente por [@phyleria](https://github.com/phyleria), con el apoyo de [@brijesh](https://github.com/brijeshthummar02) y [@Daniel](https://github.com/Danbaba1).
Para cualquier pregunta o comunicación directa, por favor contáctanos por correo a ****.
================================================
FILE: README-GM.md
================================================
---
## Über Chimoney
[Chimoney](https://chimoney.io/) ist ein globaler Zahlungsinfrastruktur-Anbieter, der es Unternehmen, Organisationen und Communities ermöglicht, Massenzahlungen sofort in über 130 Ländern zu senden. Auszahlungen können über Banküberweisungen, Mobile Money, Geschenkkarten und Airtime eingelöst werden.
## Über die Chimoney API
Die [Chimoney API](https://chimoney.readme.io/reference/introduction) ermöglicht es Ihnen, Zahlungen programmgesteuert grenzüberschreitend zu senden, zu empfangen und zu sammeln – mit Unterstützung für mehrere Kanäle wie Bankkonten, Mobile Money Wallets, Geschenkkarten und Airtime.
[Hier ist ein Video](https://www.youtube.com/watch?v=VItvZbPH9cU&t=4s), um mehr über die Chimoney API zu erfahren.
## Über die Chimoney Community-Projekte
Chimoney Community-Projekte sind Open-Source-Beiträge, die von Entwicklern, Autoren und Community-Mitgliedern unter Verwendung der Chimoney API erstellt wurden. Dazu gehören SDKs in verschiedenen Programmiersprachen, Beispielanwendungen, Integrationen und technische Artikel, die reale Anwendungsfälle hervorheben.
> **Hinweis:** Chimoney Community-Projekte werden mit unterschiedlichen Programmiersprachen und Tech-Stacks erstellt. Daher enthält jedes Projekt seine eigenen Setup-Anweisungen in einer individuellen README-Datei. Bitte lesen Sie diese README, bevor Sie das Projekt ausführen oder daran mitwirken.
## Einstieg mit der Chimoney API
Um mit der Chimoney API zu beginnen, registrieren Sie sich für ein Entwicklerkonto unter [sandbox.chimoney.io](https://sandbox.chimoney.io). Diese [Schritt-für-Schritt-Anleitung](https://www.loom.com/share/436303eb69c44f0d9757ea0c655bed89?sid=b6a0f661-721c-4731-9873-ae6f2d25780) führt Sie durch den Prozess der Kontoerstellung, Generierung Ihres API-Schlüssels und der Durchführung Ihrer ersten Testauszahlung in der Sandbox-Umgebung.
Sobald Ihr Setup abgeschlossen ist, können Sie die Chimoney API erkunden, Anfragen senden und Projekte mit realen Anwendungsfällen erstellen.
## Beitrag leisten
Chimoney Community-Projekte stehen Entwicklern, Autoren und Designern offen, die mit der Chimoney API entwickeln, schreiben oder gestalten möchten. Sie können beitragen, indem Sie SDKs, Integrationen, Beispiel-Apps oder technische Artikel mit realen Anwendungsfällen einreichen.
Um loszulegen, sehen Sie sich die [offenen Issues](https://github.com/Chimoney/chimoney-community-projects/issues) in diesem Repo an oder schlagen Sie Ihre eigene Idee vor.
Wenn Sie bereit für eine Einreichung sind, forken Sie das Repo, erstellen Sie einen Branch, nehmen Sie Ihre Änderungen vor und öffnen Sie einen Pull Request. Achten Sie darauf, eine klare Beschreibung hinzuzufügen und die Projektordnerstruktur einzuhalten. Alle Beiträge gehen in das `submissions/`-Verzeichnis, wobei Ihr Beitrag in den entsprechenden Unterordner kommt (z. B. Artikel in den `articles/`-Ordner, SDKs in den `SDKs/`-Ordner).
Die vollständigen [Beitragsrichtlinien](/CONTRIBUTING.md) finden Sie hier, um zu verstehen, wie Sie effektiv beitragen können.
## Chimoney Hacktoberfest
Chimoney nimmt seit 2022 jedes Jahr am [Hacktoberfest](https://hacktoberfest.com/) teil und lädt Entwickler, Autoren und Designer ein, zu unserer Open-Source-Community beizutragen.
Jeden Oktober erstellen wir einsteigerfreundliche **`Hacktoberfest`**-Issues, um es sowohl neuen als auch erfahrenen Mitwirkenden einfacher zu machen, sich zu beteiligen.
Wir bieten außerdem Belohnungen und Anerkennung für bedeutungsvolle Beiträge während des Hacktoberfestes. Um unsere vergangenen Hacktoberfest-Rückblicke zu lesen, zu sehen, wie Sie sich beteiligen können, und das Beste aus Ihrem Beitrag zu Chimoneys Open-Source-Projekten zu machen, lesen Sie hier mehr.
### Hacktoberfest 2025
Chimoney nimmt am Hacktoberfest 2025 teil! ✨
In diesem Jahr führen wir neben unseren bestehenden Open-Source-Projekten ein brandneues Projekt ein: **IaaS-k8s**
IaaS-k8s ist eine Multi-Cloud-Kubernetes-Infrastruktur-Deployment-Lösung, die AWS EKS und GCP GKE unterstützt und mit Pulumi und TypeScript entwickelt wurde.
➝ _Erfahren Sie mehr über das Projekt und starten Sie hier:_ [_IaaS-k8s Project_](https://github.com/Chimoney/Iaas)
Wie immer werden auch in diesem Repo offene Issues für Mitwirkende aller Erfahrungsstufen verfügbar sein.
## Treten Sie unserer Community bei
Treten Sie mit anderen, die mit der Chimoney API entwickeln, in unserem [Discord-Server](https://discord.gg/TsyKnzT4qV) in Kontakt. Bitte lesen Sie unseren [Code of Conduct](https://github.com/Chimoney/chimoney-community-projects/blob/main/CODE_OF_CONDUCT.md), bevor Sie teilnehmen.
## Kontakt
Dieses Repository wird aktiv von [@phyleria](https://github.com/phyleria) gepflegt, mit Unterstützung von [@brijesh](https://github.com/brijeshthummar02) und [@Daniel](https://github.com/Danbaba1).
Bei Fragen oder direkter Kommunikation kontaktieren Sie uns bitte per E-Mail unter ****
================================================
FILE: README-HN.md
================================================
[प्रलेखन](https://chimoney.readme.io/reference/introduction) • [डेवलपर टूलकिट](https://chimoney.io/toolkit/) • [API उपयोग केस](https://chimoney.io/api-use-cases/) • [हमसे Discord पर जुड़ें](https://discord.gg/TsyKnzT4qV) • [X पर कनेक्ट करें](https://x.com/chimoney_io)
---
## Chimoney के बारे में
[Chimoney](https://chimoney.io/) एक वैश्विक भुगतान अवसंरचना प्रदाता है जो व्यवसायों, संगठनों और समुदायों को 130+ देशों में तुरंत थोक भुगतान भेजने में सक्षम बनाता है। भुगतान बैंक ट्रांसफ़र, मोबाइल मनी, गिफ्ट कार्ड और एयरटाइम के माध्यम से रिडीम किए जा सकते हैं।
## Chimoney API के बारे में
[Chimoney API](https://chimoney.readme.io/reference/introduction) आपको प्रोग्रामेटिक तरीके से भुगतान भेजने, प्राप्त करने और एकत्रित करने की सुविधा देता है। यह कई चैनलों का समर्थन करता है, जिनमें बैंक खाते, मोबाइल मनी वॉलेट, गिफ्ट कार्ड और एयरटाइम शामिल हैं।
[यहाँ एक वीडियो](https://www.youtube.com/watch?v=VItvZbPH9cU&t=4s) है जो Chimoney API के बारे में और जानकारी देता है।
## Chimoney कम्युनिटी प्रोजेक्ट्स के बारे में
Chimoney कम्युनिटी प्रोजेक्ट्स ओपन-सोर्स योगदान हैं जिन्हें डेवलपर्स, राइटर्स और कम्युनिटी सदस्यों ने Chimoney API का उपयोग करके बनाया है। इनमें विभिन्न प्रोग्रामिंग भाषाओं में SDKs, सैंपल एप्लिकेशन्स, इंटीग्रेशन और तकनीकी लेख शामिल हैं जो वास्तविक दुनिया के उपयोग मामलों को उजागर करते हैं।
> **नोट:** Chimoney कम्युनिटी प्रोजेक्ट्स अलग-अलग प्रोग्रामिंग भाषाओं और टेक स्टैक का उपयोग करके बनाए गए हैं। प्रत्येक प्रोजेक्ट की अपनी README फाइल होती है जिसमें सेटअप निर्देश शामिल हैं। कृपया योगदान या रन करने से पहले उस प्रोजेक्ट की README ज़रूर देखें।
## Chimoney API के साथ शुरुआत करना
Chimoney API के साथ शुरुआत करने के लिए, [sandbox.chimoney.io](https://sandbox.chimoney.io) पर एक डेवलपर खाता बनाएँ। यह [स्टेप-बाय-स्टेप गाइड](https://www.loom.com/share/436303eb69c44f0d9757ea0c655bed89?sid=b6a0f661-721c-4731-9873-ae6f2d25780) आपको खाता बनाने, API key जनरेट करने और sandbox environment का उपयोग करके अपनी पहली टेस्ट पेआउट करने की प्रक्रिया दिखाएगा।
एक बार सेटअप पूरा हो जाने के बाद, आप Chimoney API को एक्सप्लोर करना शुरू कर सकते हैं, अनुरोध भेज सकते हैं और वास्तविक दुनिया के उपयोग मामलों वाले प्रोजेक्ट बना सकते हैं।
## योगदान करना
Chimoney कम्युनिटी प्रोजेक्ट्स डेवलपर्स, राइटर्स और डिज़ाइनर्स के लिए खुले हैं जो Chimoney API के साथ निर्माण करना, लिखना या बनाना चाहते हैं। आप SDKs, इंटीग्रेशन, उदाहरण एप्लिकेशन्स, या तकनीकी लेख देकर योगदान कर सकते हैं।
शुरू करने के लिए, इस रिपॉजिटरी के [open issues](https://github.com/Chimoney/chimoney-community-projects/issues) देखें या अपना विचार प्रस्तावित करें।
जब आप सबमिशन करने के लिए तैयार हों, तो रिपॉजिटरी को fork करें, एक branch बनाएँ, अपने बदलाव करें और एक pull request खोलें। कृपया एक स्पष्ट विवरण शामिल करें और प्रोजेक्ट फ़ोल्डर संरचना का पालन करें। सभी योगदान `submissions/` डायरेक्टरी में जाएंगे, जहाँ आपका योगदान संबंधित सबफ़ोल्डर में रखा जाएगा (जैसे कि लेख `articles/` फ़ोल्डर में, SDKs `SDKs/` फ़ोल्डर में)।
पूरी [Contribution Guidelines](/CONTRIBUTING.md) यहाँ पढ़ें ताकि आप प्रभावी ढंग से योगदान कर सकें।
## Chimoney Hacktoberfest
Chimoney ने [Hacktoberfest](https://hacktoberfest.com/) में 2022 से भाग लिया है, और डेवलपर्स, राइटर्स और डिज़ाइनर्स का स्वागत किया है कि वे हमारे ओपन-सोर्स समुदाय में योगदान दें।
हर अक्टूबर, हम शुरुआती-अनुकूल **`Hacktoberfest`** issues बनाते हैं ताकि नए और अनुभवी योगदानकर्ताओं दोनों के लिए योगदान करना आसान हो।
हम Hacktoberfest के दौरान सार्थक योगदानों के लिए पुरस्कार और मान्यता भी प्रदान करते हैं। हमारे पिछले Hacktoberfest recaps देखने और योगदान करने के तरीकों को जानने के लिए यहाँ पढ़ें।
### Hacktoberfest 2025
Chimoney, Hacktoberfest 2025 में भाग ले रहा है! ✨
इस साल, मौजूदा ओपन-सोर्स प्रोजेक्ट्स के साथ, हम एक नया प्रोजेक्ट पेश कर रहे हैं: **IaaS-k8s**
IaaS-k8s एक मल्टी-क्लाउड Kubernetes अवसंरचना परिनियोजन समाधान है, जो AWS EKS और GCP GKE को सपोर्ट करता है। यह Pulumi और TypeScript से बनाया गया है।
➝ _प्रोजेक्ट के बारे में और जानें और यहाँ से शुरुआत करें:_ [_IaaS-k8s Project_](https://github.com/Chimoney/Iaas)
जैसा हमेशा, इस रिपॉजिटरी में सभी स्तरों के योगदानकर्ताओं के लिए open issues उपलब्ध रहेंगे।
## हमारी कम्युनिटी से जुड़ें
Chimoney API के साथ निर्माण कर रहे अन्य लोगों से हमारे [Discord server](https://discord.gg/TsyKnzT4qV) पर जुड़ें। कृपया भाग लेने से पहले हमारा [Code of Conduct](https://github.com/Chimoney/chimoney-community-projects/blob/main/CODE_OF_CONDUCT.md) पढ़ें।
## संपर्क
यह रिपॉजिटरी सक्रिय रूप से [@phyleria](https://github.com/phyleria) द्वारा प्रबंधित की जाती है, और [@brijesh](https://github.com/brijeshthummar02) और [@Daniel](https://github.com/Danbaba1) द्वारा सहयोग प्रदान किया जाता है।
किसी भी प्रश्न या सीधे संपर्क के लिए, कृपया ईमेल करें: ****
================================================
FILE: README-JP.md
================================================
---
## Chimoney 소개
[Chimoney](https://chimoney.io/)는 전 세계 130개 이상의 국가에서 기업, 조직, 커뮤니티가 대량 결제를 즉시 보낼 수 있도록 지원하는 글로벌 결제 인프라 제공업체입니다. 송금은 은행 이체, 모바일 머니, 기프트 카드, 에어타임을 통해 수령할 수 있습니다.
## Chimoney API 소개
[Chimoney API](https://chimoney.readme.io/reference/introduction)를 사용하면 은행 계좌, 모바일 머니 지갑, 기프트 카드, 에어타임 등 다양한 채널을 통해 국경을 넘어 결제를 송수신하고 수금할 수 있습니다.
더 자세히 알아보려면 [이 영상](https://www.youtube.com/watch?v=VItvZbPH9cU&t=4s)을 확인하세요.
## Chimoney 커뮤니티 프로젝트 소개
Chimoney 커뮤니티 프로젝트는 개발자, 작가, 커뮤니티 구성원이 Chimoney API를 활용해 만든 오픈소스 기여물입니다. 여기에는 다양한 언어의 SDK, 샘플 애플리케이션, 통합, 실제 사용 사례를 다룬 기술 문서가 포함됩니다.
> **참고:** Chimoney 커뮤니티 프로젝트는 서로 다른 프로그래밍 언어와 기술 스택을 기반으로 구축됩니다. 따라서 각 프로젝트에는 개별 `README` 파일에 자체 설정 지침이 포함되어 있습니다. 반드시 해당 프로젝트의 `README`를 확인하세요.
## Chimoney API 시작하기
Chimoney API를 시작하려면 [sandbox.chimoney.io](https://sandbox.chimoney.io)에서 개발자 계정을 등록하세요. [이 단계별 가이드](https://www.loom.com/share/436303eb69c44f0d9757ea0c655bed89?sid=b6a0f661-721c-4731-9873-ae6f2d25780)를 통해 계정 생성, API 키 발급, 샌드박스 환경에서 첫 테스트 송금까지 과정을 안내받을 수 있습니다.
준비가 끝나면 Chimoney API를 탐색하고 요청을 보내며 실제 사용 사례에 기반한 프로젝트를 구축할 수 있습니다.
## 기여하기
Chimoney 커뮤니티 프로젝트는 Chimoney API를 기반으로 빌드, 작성, 창작을 하고자 하는 개발자, 작가, 디자이너에게 열려 있습니다. SDK, 통합, 예제 앱, 실제 사용 사례를 다루는 기술 문서를 제출하여 기여할 수 있습니다.
먼저 이 저장소의 [오픈 이슈](https://github.com/Chimoney/chimoney-community-projects/issues)를 확인하거나 직접 아이디어를 제안하세요.
준비가 되면 저장소를 fork하고, 브랜치를 만든 뒤 변경 사항을 작성해 pull request를 열어주세요. 명확한 설명을 포함하고 프로젝트 폴더 구조를 따르는 것이 중요합니다. 모든 기여물은 `submissions/` 디렉토리에 제출되며, 유형별로 적절한 하위 폴더에 배치됩니다(예: 글은 `articles/`, SDK는 `SDKs/`).
자세한 방법은 전체 [기여 가이드라인](/CONTRIBUTING.md)을 참고하세요.
## Chimoney Hacktoberfest
Chimoney는 2022년부터 매년 [Hacktoberfest](https://hacktoberfest.com/)에 참여하여 개발자, 작가, 디자이너가 오픈소스 커뮤니티에 기여할 수 있도록 해왔습니다.
매년 10월, 초보자와 숙련된 기여자 모두가 쉽게 참여할 수 있도록 **`Hacktoberfest`** 친화적인 이슈를 생성합니다.
Hacktoberfest 기간 동안 의미 있는 기여를 해주신 분들께는 보상과 인정을 제공합니다. 지난 Hacktoberfest 기록과 참여 방법을 확인하고, Chimoney 오픈소스 프로젝트에 기여해 보세요.
### Hacktoberfest 2025
Chimoney는 Hacktoberfest 2025에 참여합니다!✨
올해는 기존 오픈소스 프로젝트와 함께 **IaaS-k8s**라는 새로운 프로젝트를 소개합니다.
IaaS-k8s는 Pulumi와 TypeScript로 구축된 멀티 클라우드 Kubernetes 인프라 배포 솔루션으로, AWS EKS와 GCP GKE를 지원합니다.
➝ _프로젝트에 대해 더 알아보고 시작하려면 여기를 클릭하세요:_ [_IaaS-k8s 프로젝트_](https://github.com/Chimoney/Iaas)
기존과 마찬가지로, 이 저장소에서는 모든 수준의 기여자가 참여할 수 있는 오픈 이슈를 준비해 두었습니다.
## 커뮤니티 참여하기
[Discord 서버](https://discord.gg/TsyKnzT4qV)에서 Chimoney API를 활용하는 다른 개발자들과 소통하세요. 참여 전 반드시 [행동 강령](https://github.com/Chimoney/chimoney-community-projects/blob/main/CODE_OF_CONDUCT.md)을 읽어주세요.
## 문의하기
이 저장소는 [@phyleria](https://github.com/phyleria)가 주도적으로 관리하며, [@brijesh](https://github.com/brijeshthummar02), [@Daniel](https://github.com/Danbaba1)의 지원을 받고 있습니다.
문의사항이나 직접 연락이 필요한 경우 ****로 이메일을 보내주세요.
================================================
FILE: README.md
================================================
Global Payments.
One API, Access to 130+ countries.
[Documentation](https://chimoney.readme.io/reference/introduction) • [Developer toolkit](https://chimoney.io/toolkit/) • [API use cases](https://chimoney.io/api-use-cases/) • [Join us on Discord](https://discord.gg/TsyKnzT4qV) • [Connect on X](https://x.com/chimoney_io)
___
## Table of Contents
- [About](#about)
- [Chimoney](#chimoney)
- [Chimoney API](#chimoney-api)
- [Chimoney Community Projects](#chimoney-community-projects)
- [Getting Started with the Chimoney API](#getting-started-with-the-chimoney-api)
- [Contributing](#contributing)
- [Chimoney Hacktoberfest](#chimoney-hacktoberfest)
- [Join our Community](#join-our-community)
- [Contact](#contact)
## About
### Chimoney
[Chimoney](https://chimoney.io/) is a global payments infrastructure provider that enables businesses, organizations and communities to send bulk payments instantly in over 130 countries. Payouts can be redeemed via bank transfers, mobile money, gift cards, and airtime.
### Chimoney API
The [Chimoney API](https://chimoney.readme.io/reference/introduction) lets you programmatically send, receive, and collect payments across borders with support for multiple channels including bank accounts, mobile money wallets, gift cards, and airtime.
Through the integration of the Interledger Protocol (ILP), Chimoney also enables interoperable payments across networks. Developers can issue Interledger Wallet Addresses (Payment Pointers) and allow users to send and receive payments globally, powering use cases like Web Monetization and Open Payments. Learn more [**here.**](https://chimoney.io/blogs/a-developer-s-guide-to-enabling-ilp-payments-with-chimoney/)
[Here's a video](https://www.youtube.com/watch?v=VItvZbPH9cU&t=4s) to learn more about the Chimoney API.
### Chimoney Community Projects
Chimoney Community Projects are open-source contributions made by developers, writers, and community members using the Chimoney API. They include SDKs in different programming languages, sample applications, integrations, and technical articles that highlight real-world use cases.
> **Note:** Chimoney Community Projects are built using different programming languages and tech stacks. As a result, each project includes its own setup instructions in its individual README file. Be sure to check the specific README for guidance on running or contributing to that project.
## Getting Started with the Chimoney API
To get started with the Chimoney API, sign up for a developer account at [sandbox.chimoney.io](https://sandbox.chimoney.io). This [step-by-step guide](https://www.loom.com/share/436303eb69c44f0d9757ea0c655bed89?sid=b6a0f661-721c-4731-9873-ae6f2d25780) will take you through the process of creating an account, generating your API key, and making your first test payout using the sandbox environment. Once your setup is complete, you can begin exploring the Chimoney API, making requests, and building projects with real-world use cases.
## Contributing
Chimoney Community Projects are open to developers, writers and designers who want to build with, write or create around the Chimoney API. You can contribute by submitting:
- SDKs
- integrations
- example apps
- or technical articles showing real-world use cases.
To get started, explore the [open issues](https://github.com/Chimoney/chimoney-community-projects/issues) in this repo or propose your own idea.
When you're ready to make a submission:
- fork the repo
- create a branch
- make your changes
- and open a pull request.
Be sure to include a clear description and follow the project folder structure; all contributions go into the submissions/ directory, with your specific contribution placed in its relevant subfolder, for example:
- Articles in the articles/ folder
- SDKs in the SDKs/ folder
You can also read the full [Contribution Guidelines](/CONTRIBUTING.md) here to understand how to contribute effectively.
## Chimoney Hacktoberfest
Chimoney has participated in [Hacktoberfest](https://hacktoberfest.com/) every year since 2022, welcoming developers, writers, and designers to contribute to our open-source community.
Each October, we create beginner-friendly **`Hacktoberfest`** issues to make it easier for first-time and seasoned contributors alike to get involved.
We also offer rewards and recognition for meaningful contributions during Hacktoberfest. To explore our past Hacktoberfest recaps, see how you can get involved, and make the most of contributing to Chimoney's open-source projects, read more here.
### Hcktoberfest 2025
Chimoney is participating in Hacktoberfest 2025!✨
This year, along with our existing open-source projects, we’re introducing a brand-new project: **IaaS-k8s**
IaaS-k8s is a multi-cloud Kubernetes infrastructure deployment solution supporting AWS EKS and GCP GKE, built with Pulumi and TypeScript.
➝ _Learn more about the project and get started here:_ [_IaaS-k8s Project_](https://github.com/Chimoney/Iaas)
As always, we’ll still have open issues available in this repo for contributors of all levels.
### Rewards for Contributors
To recognize meaningful contributions during Hacktoberfest 2025, we’ll award $10 per substantial contribution (merged PRs that add value). Contributors will also be highlighted on our website and social channels.
> “Substantial contributions” include feature additions, integrations, SDKs, or technical articles. Minor edits/fixes or formatting changes are not eligible.
## Community Events Calendar
Stay connected with our community through upcoming Hacktoberfest events, contributor meetups, and live sessions.
→ [View the full Chimoney Community Calendar here](https://luma.com/calendar/manage/cal-uGd7p3LVZ350i8C).
## Join our Community
Connect with others building with the Chimoney API on our [Discord server](https://discord.gg/TsyKnzT4qV). Please read our [Code of Conduct](https://github.com/Chimoney/chimoney-community-projects/blob/main/CODE_OF_CONDUCT.md) before participating.
## Contact
This repository is actively maintained by [@phyleria](https://github.com/phyleria), with support from [@brijesh](https://github.com/brijeshthummar02) and [@Daniel](https://github.com/Danbaba1).
For any questions or direct communication, please reach out via email at ****.
================================================
FILE: ai-passport-and-wallet-examples/.gitignore
================================================
# Environment variables
.env
.env.local
.env.*.local
# Python
__pycache__/
*.py[cod]
*$py.class
*.so
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
*.egg-info/
.installed.cfg
*.egg
# Virtual environments
venv/
ENV/
env/
# IDE
.vscode/
.idea/
*.swp
*.swo
*~
# OS
.DS_Store
Thumbs.db
================================================
FILE: ai-passport-and-wallet-examples/README.md
================================================
# AI Passport and Wallet Examples
Working integrations demonstrating how to create AI agents with Chimoney wallets, policy controls, and autonomous payment capabilities.
## Examples
### 1. LangChain Research Agent
**Location**: `langchain-research-agent/`
A LangChain agent that autonomously pays for API access to data sources (weather, stock prices, news) with spending limits and transaction approval controls.
- Daily spending limit: $50/day
- Auto-approval for transactions ≤$10
- Manual approval required for transactions >$10
[View Example →](./langchain-research-agent/)
### 2. CrewAI Support Agent
**Location**: `crewai-support-agent/`
A CrewAI multi-agent system for customer support that autonomously issues refunds up to $100/day with L4 assurance for compliance and immutable audit trail.
- Daily refund limit: $100/day
- L4 assurance for compliance
- Immutable audit trail
[View Example →](./crewai-support-agent/)
### 3. Data Processing Agent
**Location**: `data-processing-agent/`
A custom Python agent that pays other agents for specialized analysis. Demonstrates agent-to-agent transactions with policy enforcement.
- Agent-to-agent payments
- Policy-controlled transactions
- Specialized analysis delegation
[View Example →](./data-processing-agent/)
## Getting Started
Each example includes:
- ✅ Full source code
- ✅ README with setup instructions
- ✅ Requirements/dependencies
- ✅ Environment configuration
Navigate to any example directory and follow its README for setup instructions.
## Prerequisites
- Python 3.8+
- Chimoney API key ([Get one here](https://sandbox.chimoney.io))
- Framework-specific dependencies (see individual example READMEs)
## API Documentation
- [Chimoney API v0.2.4 Documentation](https://api.chimoney.io/v0.2.4/api-docs)
- [Swagger JSON](https://api-v2-sandbox.chimoney.io/swagger.json)
## Contributing
Contributions are welcome! Please read the [Contributing Guide](../CONTRIBUTING.md) first.
## License
MIT License
## Resources
- [Chimoney Community Projects](https://github.com/Chimoney/chimoney-community-projects)
- [Chimoney Documentation](https://chimoney.readme.io)
- [Join Discord](https://discord.gg/TsyKnzT4qV)
================================================
FILE: ai-passport-and-wallet-examples/crewai-support-agent/README.md
================================================
# CrewAI Support Agent with Chimoney Wallet
A CrewAI multi-agent system for customer support that autonomously issues refunds up to $100/day with L4 assurance for compliance and immutable audit trail.
## Features
- ✅ Autonomous refund processing
- ✅ Built-in daily refund limit: $100/day (enforced by Chimoney API)
- ✅ Built-in max refund per transaction: $100 (enforced by Chimoney API)
- ✅ L4 assurance for compliance
- ✅ Immutable audit trail
- ✅ Multi-agent coordination with CrewAI
## Overview
This example demonstrates how to integrate Chimoney's AI agent wallet infrastructure with CrewAI to create a customer support system that can autonomously process refunds while maintaining compliance and audit requirements.
## Prerequisites
- Python 3.8+
- Chimoney API key ([Get one free at sandbox.chimoney.io](https://sandbox.chimoney.io))
- CrewAI installed
- OpenAI API key (or other LLM provider compatible with CrewAI)
## Installation
```bash
# Clone the repository
git clone https://github.com/Chimoney/chimoney-community-projects.git
cd chimoney-community-projects/ai-passport-and-wallet-examples/crewai-support-agent
# Install dependencies
pip install -r requirements.txt
# Set up environment variables
cp .env.example .env
# Edit .env with your API keys (CHIMONEY_API_KEY and OPENAI_API_KEY are required)
```
## Environment Variables
Create a `.env` file with the following:
```env
CHIMONEY_API_KEY=your_chimoney_api_key
CHIMONEY_SANDBOX_URL=https://api-v2-sandbox.chimoney.io
OPENAI_API_KEY=your_openai_api_key
AGENT_EMAIL=support-agent@yourdomain.com
AGENT_NAME=Support Agent
DAILY_REFUND_LIMIT=100
```
## Usage
```bash
python support_agent.py
```
## How It Works
1. **Wallet Creation**: Creates an AI agent wallet with built-in refund limits using the agents/create endpoint
2. **Automatic Limit Enforcement**: Chimoney API automatically enforces daily refund limits ($100/day) and max per transaction ($100)
3. **Refund Processing**: Processes refunds automatically - API rejects refunds exceeding limits
4. **Audit Trail**: Records all transactions with immutable audit logs
5. **Multi-Agent Coordination**: Uses CrewAI for task distribution and coordination
6. **No Manual Tracking**: Limits are enforced server-side, no need to manually track refunds
## API Endpoints Used
- `POST /v0.2.4/agents/create` - Create AI agent wallet
- `POST /v0.2.4/payouts/chimoney` - Issue refunds
- `POST /v0.2.4/accounts/transactions` - Get audit trail
- `POST /v0.2.4/accounts/issue-id-transactions` - Get transaction by ID
## Example Flow
```python
# Customer requests refund
customer_email = "customer@example.com"
refund_amount = 25.00
# Agent processes refund
agent.process_refund(customer_email, refund_amount)
# Chimoney API checks built-in limits automatically
# Refund approved (under $100/day limit, under $100 max per tx)
# Payment processed
# Audit log created
# If limit exceeded:
# Chimoney API returns error, refund rejected
# Agent receives clear error message
```
## Contributing
Contributions are welcome! Please read the [Contributing Guide](../../CONTRIBUTING.md) first.
## License
MIT License
## Resources
- [Chimoney API Documentation](https://api.chimoney.io/v0.2.4/api-docs)
- [Chimoney API Swagger (Interactive)](https://api-v2-sandbox.chimoney.io/swagger.json)
- [Get Chimoney API Key](https://sandbox.chimoney.io)
- [CrewAI Documentation](https://docs.crewai.com/)
- [Chimoney Community Projects](https://github.com/Chimoney/chimoney-community-projects)
================================================
FILE: ai-passport-and-wallet-examples/crewai-support-agent/requirements.txt
================================================
crewai>=0.1.0
langchain>=0.1.0
langchain-openai>=0.0.5
openai>=1.0.0
python-dotenv>=1.0.0
requests>=2.31.0
pydantic>=2.0.0
================================================
FILE: ai-passport-and-wallet-examples/crewai-support-agent/support_agent.py
================================================
"""
CrewAI Support Agent with Chimoney Wallet Integration
This agent autonomously issues refunds up to $100/day with L4 assurance
for compliance and immutable audit trail.
"""
import os
import requests
from datetime import datetime
from typing import Dict, List
from dotenv import load_dotenv
from crewai import Agent, Task, Crew, Process
from langchain_openai import ChatOpenAI
# Load environment variables
load_dotenv()
# Configuration
CHIMONEY_API_KEY = os.getenv("CHIMONEY_API_KEY")
CHIMONEY_BASE_URL = os.getenv("CHIMONEY_SANDBOX_URL", "https://api-v2-sandbox.chimoney.io")
OPENAI_API_KEY = os.getenv("OPENAI_API_KEY")
AGENT_EMAIL = os.getenv("AGENT_EMAIL", "support-agent@example.com")
AGENT_NAME = os.getenv("AGENT_NAME", "Support Agent")
DAILY_REFUND_LIMIT = float(os.getenv("DAILY_REFUND_LIMIT", "100"))
# Validate required API keys
if not CHIMONEY_API_KEY:
raise ValueError("CHIMONEY_API_KEY environment variable is required. Get your API key at https://sandbox.chimoney.io")
if not OPENAI_API_KEY:
raise ValueError("OPENAI_API_KEY environment variable is required")
class ChimoneyWallet:
"""Wrapper for Chimoney API operations"""
def __init__(self, api_key: str, base_url: str):
self.api_key = api_key
self.base_url = base_url
self.headers = {
"accept": "application/json",
"content-type": "application/json",
"X-API-KEY": api_key
}
self.wallet_id = None
self.audit_log = []
def create_wallet(self, name: str, email: str, daily_refund_limit: float = 100.0) -> Dict:
"""Create an AI agent wallet with built-in refund limits
Limits are enforced by the Chimoney API automatically:
- refundAmountDailyCap: Maximum refunds per day (in USD cents)
- refundAmountMaxPerTx: Maximum refund per transaction (in USD cents)
"""
url = f"{self.base_url}/v0.2.4/agents/create"
payload = {
"name": name,
"email": email,
"limits": {
"refundAmountMaxPerTx": int(daily_refund_limit * 100), # Max $100 per refund
"refundAmountDailyCap": int(daily_refund_limit * 100) # $100 daily cap
},
"capabilities": ["finance.payment.refund"]
}
response = requests.post(url, json=payload, headers=self.headers)
response.raise_for_status()
data = response.json()
if data.get("status") == "success":
# Agent wallet ID is typically in data.data.id or data.data.walletId
wallet_data = data.get("data", {})
self.wallet_id = wallet_data.get("id") or wallet_data.get("walletId") or wallet_data.get("subAccount")
return wallet_data
raise Exception(f"Failed to create agent wallet: {data}")
def process_refund(self, customer_email: str, amount: float, reason: str = "Customer refund") -> Dict:
"""Process a refund to a customer using Chimoney payout
Limits are automatically enforced by the Chimoney API.
If limits are exceeded, the API will return an error.
"""
url = f"{self.base_url}/v0.2.4/payouts/chimoney"
payload = {
"chimoneys": [{
"email": customer_email,
"valueInUSD": amount,
"reason": f"Refund: {reason}"
}]
}
# Include subAccount if wallet_id is available
if self.wallet_id:
payload["subAccount"] = self.wallet_id
response = requests.post(url, json=payload, headers=self.headers)
# Check for limit violations (API will return 400/403 for limit exceeded)
if response.status_code in [400, 403]:
error_data = response.json()
error_msg = error_data.get("error") or error_data.get("message", "Refund failed")
raise Exception(f"Refund limit exceeded: {error_msg}")
response.raise_for_status()
data = response.json()
if data.get("status") == "success":
# Extract issueID from response
payout_data = data.get("data", {})
chimoneys = payout_data.get("chimoneys", [])
transaction_id = chimoneys[0].get("issueID", "unknown") if chimoneys else payout_data.get("issueID", "unknown")
# Create audit log entry
audit_entry = {
"timestamp": datetime.now().isoformat(),
"transaction_id": transaction_id,
"type": "refund",
"amount": amount,
"customer_email": customer_email,
"reason": reason,
"l4_assurance": True
}
self.audit_log.append(audit_entry)
return {
"transaction_id": transaction_id,
"amount": amount,
"audit_entry": audit_entry
}
raise Exception(f"Refund failed: {data}")
def get_audit_trail(self) -> List[Dict]:
"""Get immutable audit trail"""
return self.audit_log.copy()
def get_transaction_by_id(self, issue_id: str) -> Dict:
"""Get transaction details by issue ID"""
url = f"{self.base_url}/v0.2.4/accounts/issue-id-transactions"
params = {"issueID": issue_id}
response = requests.post(url, json={}, headers=self.headers, params=params)
response.raise_for_status()
return response.json()
class SupportAgent:
"""CrewAI support agent with Chimoney wallet integration"""
def __init__(self):
self.wallet = ChimoneyWallet(CHIMONEY_API_KEY, CHIMONEY_BASE_URL)
self.initialize_wallet()
self.llm = ChatOpenAI(model="gpt-4", temperature=0, api_key=OPENAI_API_KEY)
self.crew = self._create_crew()
def initialize_wallet(self):
"""Initialize the agent's wallet with built-in refund limits"""
try:
wallet_data = self.wallet.create_wallet(
AGENT_NAME,
AGENT_EMAIL,
daily_refund_limit=DAILY_REFUND_LIMIT
)
print(f"✅ Wallet created: {wallet_data.get('id')}")
print(f" Daily refund limit: ${DAILY_REFUND_LIMIT} (enforced by API)")
print(f" Max refund per transaction: ${DAILY_REFUND_LIMIT} (enforced by API)")
except Exception as e:
print(f"⚠️ Wallet initialization error: {e}")
print("Continuing with limited functionality...")
def _create_crew(self) -> Crew:
"""Create CrewAI crew with specialized agents"""
# Refund Processor Agent
refund_agent = Agent(
role="Refund Processor",
goal="Process customer refunds efficiently and within daily limits",
backstory="""You are a specialized refund processor with access to
payment infrastructure. You can process refunds up to $100/day automatically.
Always check daily limits before processing.""",
verbose=True,
allow_delegation=False,
llm=self.llm
)
# Support Coordinator Agent
coordinator_agent = Agent(
role="Support Coordinator",
goal="Coordinate customer support requests and delegate refund processing",
backstory="""You coordinate customer support operations and delegate
refund requests to the refund processor when appropriate.""",
verbose=True,
allow_delegation=True,
llm=self.llm
)
return Crew(
agents=[coordinator_agent, refund_agent],
tasks=[],
process=Process.sequential,
verbose=True
)
def process_refund_request(self, customer_email: str, amount: float, reason: str) -> Dict:
"""Process a refund request
Limits are automatically enforced by the Chimoney API.
"""
try:
# Process refund (API will enforce limits)
result = self.wallet.process_refund(customer_email, amount, reason)
return {
"success": True,
"transaction_id": result["transaction_id"],
"amount": amount,
"message": f"Refund of ${amount:.2f} processed successfully",
"audit_entry": result["audit_entry"]
}
except Exception as e:
return {
"success": False,
"error": str(e)
}
def get_daily_summary(self) -> Dict:
"""Get daily refund summary"""
# Calculate today's refunds from audit log
today = datetime.now().date()
today_refunds = []
for e in self.wallet.audit_log:
try:
timestamp_str = e["timestamp"].replace("Z", "+00:00")
entry_date = datetime.fromisoformat(timestamp_str).date()
if entry_date == today:
today_refunds.append(e)
except (ValueError, AttributeError, KeyError):
# Skip invalid timestamps
continue
daily_refunded = sum(e["amount"] for e in today_refunds)
return {
"daily_refunded": daily_refunded,
"daily_limit": DAILY_REFUND_LIMIT,
"remaining": DAILY_REFUND_LIMIT - daily_refunded,
"transactions_today": len(today_refunds)
}
def get_audit_trail(self) -> List[Dict]:
"""Get immutable audit trail"""
return self.wallet.get_audit_trail()
def main():
"""Main function to run the support agent"""
print("🚀 Initializing Support Agent with Chimoney Wallet...")
print(f"💰 Daily Refund Limit: ${DAILY_REFUND_LIMIT}")
print(f"✅ L4 Assurance: Enabled")
print(f"📋 Audit Trail: Immutable")
print()
agent = SupportAgent()
# Example refund requests
examples = [
{"email": "customer1@example.com", "amount": 25.00, "reason": "Product defect"},
{"email": "customer2@example.com", "amount": 50.00, "reason": "Service cancellation"},
{"email": "customer3@example.com", "amount": 30.00, "reason": "Billing error"},
]
print("Processing example refund requests:")
print("="*50)
for i, refund in enumerate(examples, 1):
print(f"\n{i}. Processing refund for {refund['email']}...")
result = agent.process_refund_request(
refund["email"],
refund["amount"],
refund["reason"]
)
if result["success"]:
print(f" ✅ {result['message']}")
print(f" 📝 Transaction ID: {result['transaction_id']}")
else:
print(f" ❌ {result.get('message', result.get('error', 'Unknown error'))}")
print("\n" + "="*50)
print("Daily Summary:")
summary = agent.get_daily_summary()
print(f" Refunded: ${summary['daily_refunded']:.2f} / ${summary['daily_limit']:.2f}")
print(f" Remaining: ${summary['remaining']:.2f}")
print(f" Transactions: {summary['transactions_today']}")
print("\n" + "="*50)
print("Audit Trail (Last 5 entries):")
audit_trail = agent.get_audit_trail()
for entry in audit_trail[-5:]:
print(f" [{entry['timestamp']}] ${entry['amount']:.2f} - {entry['reason']} (ID: {entry['transaction_id']})")
if __name__ == "__main__":
main()
================================================
FILE: ai-passport-and-wallet-examples/data-processing-agent/README.md
================================================
# Data Processing Agent with Chimoney Wallet
A custom Python agent that pays other agents for specialized analysis. Demonstrates agent-to-agent transactions with policy enforcement.
## Features
- ✅ Agent-to-agent payments
- ✅ Built-in transaction limits (enforced by Chimoney API)
- ✅ Policy-controlled transactions with automatic enforcement
- ✅ Specialized analysis delegation
- ✅ Transaction tracking and audit
## Overview
This example demonstrates how to create a data processing agent that can delegate specialized analysis tasks to other agents and pay them using Chimoney's wallet infrastructure. This enables a multi-agent economy where agents can transact with each other.
## Prerequisites
- Python 3.8+
- Chimoney API key ([Get one free at sandbox.chimoney.io](https://sandbox.chimoney.io))
## Installation
```bash
# Clone the repository
git clone https://github.com/Chimoney/chimoney-community-projects.git
cd chimoney-community-projects/ai-passport-and-wallet-examples/data-processing-agent
# Install dependencies
pip install -r requirements.txt
# Set up environment variables
cp .env.example .env
# Edit .env with your API key (CHIMONEY_API_KEY is required)
```
## Environment Variables
Create a `.env` file with the following:
```env
CHIMONEY_API_KEY=your_chimoney_api_key
CHIMONEY_SANDBOX_URL=https://api-v2-sandbox.chimoney.io
AGENT_EMAIL=data-agent@yourdomain.com
AGENT_NAME=Data Processing Agent
```
## Usage
```bash
python data_agent.py
```
## How It Works
1. **Wallet Creation**: Creates AI agent wallets with built-in limits for the main agent ($1000/day, $100/tx) and worker agents ($500/day, $50/tx) using agents/create
2. **Task Delegation**: Delegates specialized analysis tasks to worker agents
3. **Payment Processing**: Pays worker agents for completed tasks - API automatically enforces limits
4. **Automatic Policy Enforcement**: Chimoney API enforces spending policies and transaction limits server-side
5. **Result Aggregation**: Aggregates results from multiple worker agents
6. **No Manual Tracking**: Limits are enforced server-side, no need to manually track spending
## API Endpoints Used
- `POST /v0.2.4/agents/create` - Create AI agent wallets
- `POST /v0.2.4/multicurrency-wallets/transfer` - Transfer funds between agents
- `POST /v0.2.4/payouts/chimoney` - Pay worker agents via email
- `POST /v0.2.4/payouts/interledger-wallet-address` - Pay worker agents via Interledger
- `POST /v0.2.4/accounts/transactions` - Track transactions
## Example Flow
```python
# Main agent needs specialized analysis
task = "Analyze sales data for Q4"
# Delegate to specialized agent
result = agent.delegate_task(
task=task,
worker_agent="analytics-agent",
payment_amount=15.00
)
# Chimoney API checks built-in limits automatically
# Payment approved (under $100 max per tx, under $1000 daily limit)
# Worker agent completes task
# Payment processed automatically
# Results returned to main agent
# If limit exceeded:
# Chimoney API returns error, payment rejected
# Agent receives clear error message
```
## Contributing
Contributions are welcome! Please read the [Contributing Guide](../../CONTRIBUTING.md) first.
## License
MIT License
## Resources
- [Chimoney API Documentation](https://api.chimoney.io/v0.2.4/api-docs)
- [Chimoney API Swagger (Interactive)](https://api-v2-sandbox.chimoney.io/swagger.json)
- [Get Chimoney API Key](https://sandbox.chimoney.io)
- [Chimoney Community Projects](https://github.com/Chimoney/chimoney-community-projects)
================================================
FILE: ai-passport-and-wallet-examples/data-processing-agent/data_agent.py
================================================
"""
Data Processing Agent with Chimoney Wallet Integration
This agent pays other agents for specialized analysis, demonstrating
agent-to-agent transactions with policy enforcement.
"""
import os
import requests
from datetime import datetime
from typing import Dict, List
from dotenv import load_dotenv
# Load environment variables
load_dotenv()
# Configuration
CHIMONEY_API_KEY = os.getenv("CHIMONEY_API_KEY")
CHIMONEY_BASE_URL = os.getenv("CHIMONEY_SANDBOX_URL", "https://api-v2-sandbox.chimoney.io")
AGENT_EMAIL = os.getenv("AGENT_EMAIL", "data-agent@example.com")
AGENT_NAME = os.getenv("AGENT_NAME", "Data Processing Agent")
# Validate required API key
if not CHIMONEY_API_KEY:
raise ValueError("CHIMONEY_API_KEY environment variable is required. Get your API key at https://sandbox.chimoney.io")
class ChimoneyWallet:
"""Wrapper for Chimoney API operations"""
def __init__(self, api_key: str, base_url: str):
self.api_key = api_key
self.base_url = base_url
self.headers = {
"accept": "application/json",
"content-type": "application/json",
"X-API-KEY": api_key
}
self.wallet_id = None
def create_wallet(self, name: str, email: str, daily_limit: float = 1000.0, max_per_tx: float = 100.0) -> Dict:
"""Create an AI agent wallet with built-in limits
Limits are enforced by the Chimoney API automatically:
- dailyCap: Maximum spending per day (in USD cents)
- maxPerTx: Maximum per transaction (in USD cents)
"""
url = f"{self.base_url}/v0.2.4/agents/create"
payload = {
"name": name,
"email": email,
"limits": {
"USD": {
"maxPerTx": int(max_per_tx * 100), # Convert to cents
"dailyCap": int(daily_limit * 100) # Convert to cents
}
},
"capabilities": ["finance.payment.payout", "wallet.transfer"]
}
response = requests.post(url, json=payload, headers=self.headers)
response.raise_for_status()
data = response.json()
if data.get("status") == "success":
# Agent wallet ID is typically in data.data.id or data.data.walletId
wallet_data = data.get("data", {})
self.wallet_id = wallet_data.get("id") or wallet_data.get("walletId") or wallet_data.get("subAccount")
return wallet_data
raise Exception(f"Failed to create agent wallet: {data}")
def transfer_to_agent(self, destination_wallet_id: str, amount: float, currency: str = "USD", narration: str = "") -> Dict:
"""Transfer funds to another agent's wallet"""
if not self.wallet_id:
raise Exception("Source wallet not initialized")
url = f"{self.base_url}/v0.2.4/multicurrency-wallets/transfer"
payload = {
"sourceWalletID": self.wallet_id,
"destinationWalletID": destination_wallet_id,
"amount": amount,
"currency": currency,
"narration": narration or f"Payment for agent service"
}
response = requests.post(url, json=payload, headers=self.headers)
response.raise_for_status()
data = response.json()
if data.get("status") == "success":
return data["data"]
raise Exception(f"Transfer failed: {data}")
def pay_agent_via_chimoney(self, amount: float, agent_email: str, task_description: str) -> Dict:
"""Pay an agent via Chimoney payout
Limits are automatically enforced by the Chimoney API.
If limits are exceeded, the API will return an error.
"""
url = f"{self.base_url}/v0.2.4/payouts/chimoney"
payload = {
"chimoneys": [{
"email": agent_email,
"valueInUSD": amount,
"reason": f"Agent payment: {task_description}"
}]
}
# Include subAccount if wallet_id is available
if self.wallet_id:
payload["subAccount"] = self.wallet_id
response = requests.post(url, json=payload, headers=self.headers)
# Check for limit violations (API will return 400/403 for limit exceeded)
if response.status_code in [400, 403]:
error_data = response.json()
error_msg = error_data.get("error") or error_data.get("message", "Payment failed")
raise Exception(f"Transaction limit exceeded: {error_msg}")
response.raise_for_status()
data = response.json()
if data.get("status") == "success":
return data.get("data", {})
raise Exception(f"Payment failed: {data}")
def pay_agent_via_interledger(self, amount: float, interledger_address: str, task_description: str) -> Dict:
"""Pay an agent via Interledger wallet address"""
url = f"{self.base_url}/v0.2.4/payouts/interledger-wallet-address"
payload = {
"payments": [{
"interledgerWalletAddress": interledger_address,
"valueInUSD": amount,
"metadata": {"task": task_description}
}]
}
# Include subAccount if wallet_id is available
if self.wallet_id:
payload["subAccount"] = self.wallet_id
response = requests.post(url, json=payload, headers=self.headers)
response.raise_for_status()
data = response.json()
if data.get("status") == "success":
return data.get("data", {})
raise Exception(f"Interledger payment failed: {data}")
def get_transactions(self, limit: int = 10) -> List[Dict]:
"""Get transaction history"""
if not self.wallet_id:
return []
url = f"{self.base_url}/v0.2.4/accounts/transactions"
payload = {
"subAccount": self.wallet_id,
"limit": limit,
"page": 1
}
response = requests.post(url, json=payload, headers=self.headers)
response.raise_for_status()
data = response.json()
if data.get("status") == "success":
return data.get("data", {}).get("transactions", [])
return []
class WorkerAgent:
"""Represents a specialized worker agent"""
def __init__(self, name: str, email: str, specialization: str, wallet: ChimoneyWallet):
self.name = name
self.email = email
self.specialization = specialization
self.wallet = wallet
self.wallet_id = None
def initialize(self):
"""Initialize the worker agent's wallet with built-in limits"""
wallet_data = self.wallet.create_wallet(
self.name,
self.email,
daily_limit=500.0, # $500 daily limit for worker agents
max_per_tx=50.0 # $50 max per transaction
)
self.wallet_id = wallet_data.get("id")
return wallet_data
def process_task(self, task: str) -> Dict:
"""Process a specialized task"""
# In production, this would perform actual analysis
return {
"agent": self.name,
"specialization": self.specialization,
"task": task,
"result": f"Analysis completed by {self.name} specializing in {self.specialization}",
"timestamp": datetime.now().isoformat()
}
class DataProcessingAgent:
"""Main data processing agent that delegates to worker agents"""
def __init__(self):
self.wallet = ChimoneyWallet(CHIMONEY_API_KEY, CHIMONEY_BASE_URL)
self.initialize_wallet()
self.worker_agents = {}
self.transaction_log = []
def initialize_wallet(self):
"""Initialize the main agent's wallet with built-in limits"""
try:
wallet_data = self.wallet.create_wallet(
AGENT_NAME,
AGENT_EMAIL,
daily_limit=1000.0, # $1000 daily limit
max_per_tx=100.0 # $100 max per transaction
)
print(f"✅ Main agent wallet created: {wallet_data.get('id')}")
print(f" Daily limit: $1000 (enforced by API)")
print(f" Max per transaction: $100 (enforced by API)")
except Exception as e:
print(f"⚠️ Wallet initialization error: {e}")
def register_worker_agent(self, name: str, email: str, specialization: str):
"""Register a worker agent"""
worker_wallet = ChimoneyWallet(CHIMONEY_API_KEY, CHIMONEY_BASE_URL)
worker = WorkerAgent(name, email, specialization, worker_wallet)
worker.initialize()
self.worker_agents[name] = worker
print(f"✅ Worker agent registered: {name} ({specialization})")
return worker
def delegate_task(self, task: str, worker_agent_name: str, payment_amount: float) -> Dict:
"""Delegate a task to a worker agent and pay them"""
if worker_agent_name not in self.worker_agents:
raise Exception(f"Worker agent '{worker_agent_name}' not found")
worker = self.worker_agents[worker_agent_name]
# Process the task
result = worker.process_task(task)
# Pay the worker agent
try:
payment_result = self.wallet.pay_agent_via_chimoney(
payment_amount,
worker.email,
task
)
# Extract issueID from response
chimoneys = payment_result.get("chimoneys", [])
transaction_id = chimoneys[0].get("issueID", "unknown") if chimoneys else payment_result.get("issueID", "unknown")
# Log the transaction
transaction_log_entry = {
"timestamp": datetime.now().isoformat(),
"worker_agent": worker_agent_name,
"task": task,
"payment_amount": payment_amount,
"transaction_id": transaction_id,
"result": result
}
self.transaction_log.append(transaction_log_entry)
return {
"success": True,
"result": result,
"payment": {
"amount": payment_amount,
"transaction_id": transaction_id
},
"transaction_log": transaction_log_entry
}
except Exception as e:
return {
"success": False,
"result": result,
"error": str(e)
}
def get_transaction_history(self) -> List[Dict]:
"""Get transaction history"""
return self.transaction_log.copy()
def main():
"""Main function to demonstrate agent-to-agent transactions"""
print("🚀 Initializing Data Processing Agent...")
print()
agent = DataProcessingAgent()
# Register worker agents
print("Registering worker agents:")
print("="*50)
agent.register_worker_agent(
"analytics-agent",
"analytics@example.com",
"Data Analytics"
)
agent.register_worker_agent(
"ml-agent",
"ml@example.com",
"Machine Learning"
)
agent.register_worker_agent(
"stats-agent",
"stats@example.com",
"Statistical Analysis"
)
print("\n" + "="*50)
print("Delegating tasks to worker agents:")
print("="*50)
# Delegate tasks
tasks = [
{
"task": "Analyze sales data for Q4 2024",
"worker": "analytics-agent",
"payment": 20.00
},
{
"task": "Build predictive model for customer churn",
"worker": "ml-agent",
"payment": 35.00
},
{
"task": "Perform statistical significance testing",
"worker": "stats-agent",
"payment": 15.00
}
]
for i, task_info in enumerate(tasks, 1):
print(f"\n{i}. Task: {task_info['task']}")
print(f" Worker: {task_info['worker']}")
print(f" Payment: ${task_info['payment']:.2f}")
result = agent.delegate_task(
task_info["task"],
task_info["worker"],
task_info["payment"]
)
if result["success"]:
print(f" ✅ Task completed")
print(f" 💰 Payment processed: ${result['payment']['amount']:.2f}")
print(f" 📝 Transaction ID: {result['payment']['transaction_id']}")
else:
print(f" ❌ Error: {result.get('error', 'Unknown error')}")
print("\n" + "="*50)
print("Transaction History:")
print("="*50)
history = agent.get_transaction_history()
for entry in history:
print(f"\n[{entry['timestamp']}]")
print(f" Worker: {entry['worker_agent']}")
print(f" Task: {entry['task']}")
print(f" Payment: ${entry['payment_amount']:.2f}")
print(f" Transaction ID: {entry['transaction_id']}")
if __name__ == "__main__":
main()
================================================
FILE: ai-passport-and-wallet-examples/data-processing-agent/requirements.txt
================================================
python-dotenv>=1.0.0
requests>=2.31.0
pydantic>=2.0.0
================================================
FILE: ai-passport-and-wallet-examples/langchain-research-agent/README.md
================================================
# LangChain Research Agent with Chimoney Wallet
A LangChain agent that autonomously pays for API access to data sources (weather, stock prices, news) with spending limits and transaction approval controls.
## Features
- ✅ Autonomous API payments for data sources
- ✅ Built-in daily spending limit: $50/day (enforced by Chimoney API)
- ✅ Built-in max per transaction: $10 (enforced by Chimoney API)
- ✅ Policy-controlled wallet with automatic limit enforcement
- ✅ Full audit trail for compliance
## Overview
This example demonstrates how to integrate Chimoney's AI agent wallet infrastructure with LangChain to create a research agent that can autonomously pay for API access while maintaining spending controls and compliance.
## Prerequisites
- Python 3.8+
- Chimoney API key ([Get one free at sandbox.chimoney.io](https://sandbox.chimoney.io))
- LangChain installed
- OpenAI API key (or other LLM provider compatible with LangChain)
## Installation
```bash
# Clone the repository
git clone https://github.com/Chimoney/chimoney-community-projects.git
cd chimoney-community-projects/ai-passport-and-wallet-examples/langchain-research-agent
# Install dependencies
pip install -r requirements.txt
# Set up environment variables
cp .env.example .env
# Edit .env with your API keys (CHIMONEY_API_KEY and OPENAI_API_KEY are required)
```
## Environment Variables
Create a `.env` file with the following:
```env
CHIMONEY_API_KEY=your_chimoney_api_key
CHIMONEY_SANDBOX_URL=https://api-v2-sandbox.chimoney.io
OPENAI_API_KEY=your_openai_api_key
AGENT_EMAIL=research-agent@yourdomain.com
AGENT_NAME=Research Agent
DAILY_LIMIT=50
APPROVAL_THRESHOLD=10
```
## Usage
```bash
python research_agent.py
```
## How It Works
1. **Wallet Creation**: Creates an AI agent wallet with built-in limits using the agents/create endpoint
2. **Automatic Limit Enforcement**: Chimoney API automatically enforces daily spending limits ($50/day) and max per transaction ($10)
3. **API Integration**: Integrates with data APIs (weather, stocks, news)
4. **Payment Processing**: Automatically pays for API access - API rejects transactions exceeding limits
5. **No Manual Tracking**: Limits are enforced server-side, no need to manually track spending
## API Endpoints Used
- `POST /v0.2.4/agents/create` - Create AI agent wallet
- `POST /v0.2.4/accounts/issue-wallet-address` - Issue payment pointer
- `POST /v0.2.4/payouts/chimoney` - Send payments for API access
- `POST /v0.2.4/accounts/transactions` - Check transaction history
## Example Flow
```python
# Agent needs weather data
agent.query("What's the weather in New York?")
# Payment attempt: $5
# Chimoney API checks built-in limits automatically
# Transaction approved (under $10 max per tx, under $50 daily limit)
# API call made, data returned
# If limit exceeded:
# Chimoney API returns error, transaction rejected
# Agent receives clear error message
```
## Contributing
Contributions are welcome! Please read the [Contributing Guide](../../CONTRIBUTING.md) first.
## License
MIT License
## Resources
- [Chimoney API Documentation](https://api.chimoney.io/v0.2.4/api-docs)
- [Chimoney API Swagger (Interactive)](https://api-v2-sandbox.chimoney.io/swagger.json)
- [Get Chimoney API Key](https://sandbox.chimoney.io)
- [LangChain Documentation](https://python.langchain.com/)
- [Chimoney Community Projects](https://github.com/Chimoney/chimoney-community-projects)
================================================
FILE: ai-passport-and-wallet-examples/langchain-research-agent/requirements.txt
================================================
langchain>=0.1.0
langchain-openai>=0.0.5
openai>=1.0.0
python-dotenv>=1.0.0
requests>=2.31.0
pydantic>=2.0.0
================================================
FILE: ai-passport-and-wallet-examples/langchain-research-agent/research_agent.py
================================================
"""
LangChain Research Agent with Chimoney Wallet Integration
This agent autonomously pays for API access to data sources (weather, stock prices, news)
with spending limits and transaction approval controls.
"""
import os
import requests
from datetime import datetime
from typing import Dict, List
from dotenv import load_dotenv
from langchain.agents import AgentExecutor, create_openai_tools_agent
from langchain_openai import ChatOpenAI
from langchain.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain.tools import Tool
# Load environment variables
load_dotenv()
# Configuration
CHIMONEY_API_KEY = os.getenv("CHIMONEY_API_KEY")
CHIMONEY_BASE_URL = os.getenv("CHIMONEY_SANDBOX_URL", "https://api-v2-sandbox.chimoney.io")
OPENAI_API_KEY = os.getenv("OPENAI_API_KEY")
AGENT_EMAIL = os.getenv("AGENT_EMAIL", "research-agent@example.com")
AGENT_NAME = os.getenv("AGENT_NAME", "Research Agent")
DAILY_LIMIT = float(os.getenv("DAILY_LIMIT", "50"))
APPROVAL_THRESHOLD = float(os.getenv("APPROVAL_THRESHOLD", "10"))
# Validate required API keys
if not CHIMONEY_API_KEY:
raise ValueError("CHIMONEY_API_KEY environment variable is required. Get your API key at https://sandbox.chimoney.io")
if not OPENAI_API_KEY:
raise ValueError("OPENAI_API_KEY environment variable is required")
class ChimoneyWallet:
"""Wrapper for Chimoney API operations"""
def __init__(self, api_key: str, base_url: str):
self.api_key = api_key
self.base_url = base_url
self.headers = {
"accept": "application/json",
"content-type": "application/json",
"X-API-KEY": api_key
}
self.wallet_id = None
def create_wallet(self, name: str, email: str, daily_limit: float = 50.0, approval_threshold: float = 10.0) -> Dict:
"""Create an AI agent wallet with built-in limits
Limits are enforced by the Chimoney API automatically:
- dailyCap: Maximum spending per day (in USD cents)
- maxPerTx: Maximum per transaction (in USD cents)
- approvalRequired: Whether transactions require manual approval
"""
url = f"{self.base_url}/v0.2.4/agents/create"
payload = {
"name": name,
"email": email,
"limits": {
"USD": {
"maxPerTx": int(approval_threshold * 100), # Convert to cents
"dailyCap": int(daily_limit * 100) # Convert to cents
},
"approvalRequired": False # Auto-approve transactions within limits
},
"capabilities": ["finance.payment.payout"]
}
response = requests.post(url, json=payload, headers=self.headers)
response.raise_for_status()
data = response.json()
if data.get("status") == "success":
# Agent wallet ID is typically in data.data.id or data.data.walletId
wallet_data = data.get("data", {})
self.wallet_id = wallet_data.get("id") or wallet_data.get("walletId") or wallet_data.get("subAccount")
return wallet_data
raise Exception(f"Failed to create agent wallet: {data}")
def issue_payment_pointer(self, user_id: str, ilp_username: str) -> Dict:
"""Issue an Interledger payment pointer for the wallet"""
url = f"{self.base_url}/v0.2.4/accounts/issue-wallet-address"
payload = {
"userID": user_id,
"ilpUsername": ilp_username
}
response = requests.post(url, json=payload, headers=self.headers)
response.raise_for_status()
return response.json()
def pay_for_api_access(self, amount: float, api_name: str, recipient_email: str) -> Dict:
"""Pay for API access using Chimoney payout
Limits are automatically enforced by the Chimoney API.
If limits are exceeded, the API will return an error.
"""
url = f"{self.base_url}/v0.2.4/payouts/chimoney"
payload = {
"chimoneys": [{
"email": recipient_email,
"valueInUSD": amount,
"reason": f"API access payment: {api_name}"
}]
}
# Include subAccount if wallet_id is available
if self.wallet_id:
payload["subAccount"] = self.wallet_id
response = requests.post(url, json=payload, headers=self.headers)
# Check for limit violations (API will return 400/403 for limit exceeded)
if response.status_code in [400, 403]:
error_data = response.json()
error_msg = error_data.get("error") or error_data.get("message", "Payment failed")
raise Exception(f"Transaction limit exceeded: {error_msg}")
response.raise_for_status()
data = response.json()
if data.get("status") == "success":
return data.get("data", {})
raise Exception(f"Payment failed: {data}")
def get_transaction_history(self, limit: int = 10) -> List[Dict]:
"""Get transaction history for the wallet"""
if not self.wallet_id:
return []
url = f"{self.base_url}/v0.2.4/accounts/transactions"
payload = {
"subAccount": self.wallet_id,
"limit": limit,
"page": 1
}
response = requests.post(url, json=payload, headers=self.headers)
response.raise_for_status()
data = response.json()
if data.get("status") == "success":
return data.get("data", {}).get("transactions", [])
return []
class ResearchAgent:
"""LangChain agent with Chimoney wallet integration"""
def __init__(self):
self.wallet = ChimoneyWallet(CHIMONEY_API_KEY, CHIMONEY_BASE_URL)
self.initialize_wallet()
self.llm = ChatOpenAI(model="gpt-4", temperature=0, api_key=OPENAI_API_KEY)
self.tools = self._create_tools()
self.agent = self._create_agent()
def initialize_wallet(self):
"""Initialize the agent's wallet with built-in limits"""
try:
wallet_data = self.wallet.create_wallet(
AGENT_NAME,
AGENT_EMAIL,
daily_limit=DAILY_LIMIT,
approval_threshold=APPROVAL_THRESHOLD
)
print(f"✅ Wallet created: {wallet_data.get('id')}")
print(f" Daily limit: ${DAILY_LIMIT} (enforced by API)")
print(f" Max per transaction: ${APPROVAL_THRESHOLD} (enforced by API)")
# Issue payment pointer
if wallet_data.get("id"):
pointer_data = self.wallet.issue_payment_pointer(
wallet_data["id"],
"research-agent"
)
print(f"✅ Payment pointer issued: {pointer_data}")
except Exception as e:
print(f"⚠️ Wallet initialization error: {e}")
print("Continuing with limited functionality...")
def _create_tools(self) -> List[Tool]:
"""Create tools for the agent"""
def get_weather_data(query: str) -> str:
"""Get weather data. Costs $5 per query."""
try:
amount = 5.0
self.wallet.pay_for_api_access(amount, "Weather API", "weather-api@example.com")
# In production, make actual API call here
return f"Weather data for {query}: Sunny, 72°F (Paid ${amount} for API access)"
except Exception as e:
return f"Error accessing weather API: {str(e)}"
def get_stock_price(symbol: str) -> str:
"""Get stock price data. Costs $8 per query."""
try:
amount = 8.0
self.wallet.pay_for_api_access(amount, "Stock API", "stock-api@example.com")
# In production, make actual API call here
return f"Stock price for {symbol}: $150.25 (Paid ${amount} for API access)"
except Exception as e:
return f"Error accessing stock API: {str(e)}"
def get_news(query: str) -> str:
"""Get news data. Costs $3 per query."""
try:
amount = 3.0
self.wallet.pay_for_api_access(amount, "News API", "news-api@example.com")
# In production, make actual API call here
return f"News for {query}: Latest headlines... (Paid ${amount} for API access)"
except Exception as e:
return f"Error accessing news API: {str(e)}"
def check_spending() -> str:
"""Check current daily spending and remaining budget."""
# Get transaction history to calculate current spending
transactions = self.wallet.get_transaction_history(limit=100)
today = datetime.now().date()
today_spent = 0.0
for t in transactions:
if t.get("issueDate"):
try:
# Handle different date formats
issue_date_str = t["issueDate"].replace("Z", "+00:00")
issue_date = datetime.fromisoformat(issue_date_str).date()
if issue_date == today:
today_spent += float(t.get("valueInUSD", 0))
except (ValueError, AttributeError):
# Skip invalid date formats
continue
remaining = DAILY_LIMIT - today_spent
return f"Daily spending: ${today_spent:.2f} / ${DAILY_LIMIT:.2f}. Remaining: ${remaining:.2f}"
return [
Tool(
name="get_weather",
func=get_weather_data,
description="Get weather information for a location. Costs $5 per query."
),
Tool(
name="get_stock_price",
func=get_stock_price,
description="Get current stock price for a symbol. Costs $8 per query."
),
Tool(
name="get_news",
func=get_news,
description="Get news articles for a topic. Costs $3 per query."
),
Tool(
name="check_spending",
func=check_spending,
description="Check current daily spending and remaining budget."
)
]
def _create_agent(self) -> AgentExecutor:
"""Create the LangChain agent"""
prompt = ChatPromptTemplate.from_messages([
("system", """You are a research agent with access to paid data APIs.
You have a daily spending limit of ${daily_limit} and max per transaction of ${approval_threshold}.
These limits are automatically enforced by the Chimoney API - transactions exceeding limits will be rejected.
Always check spending before making expensive queries.""".format(
daily_limit=DAILY_LIMIT,
approval_threshold=APPROVAL_THRESHOLD
)),
("user", "{input}"),
MessagesPlaceholder(variable_name="agent_scratchpad"),
])
agent = create_openai_tools_agent(self.llm, self.tools, prompt)
return AgentExecutor(agent=agent, tools=self.tools, verbose=True)
def query(self, question: str) -> str:
"""Query the agent"""
try:
result = self.agent.invoke({"input": question})
return result.get("output", "No response generated")
except Exception as e:
return f"Error: {str(e)}"
def main():
"""Main function to run the research agent"""
print("🚀 Initializing Research Agent with Chimoney Wallet...")
print(f"📊 Daily Limit: ${DAILY_LIMIT}")
print(f"✅ Auto-approval threshold: ${APPROVAL_THRESHOLD}")
print()
agent = ResearchAgent()
# Example queries
examples = [
"What's the weather in New York?",
"What's the current price of AAPL stock?",
"Get me the latest news about AI",
"Check my spending",
]
print("Example queries:")
for i, query in enumerate(examples, 1):
print(f"{i}. {query}")
print("\n" + "="*50)
print("Agent is ready! Try asking questions.")
print("="*50 + "\n")
# Interactive mode
while True:
try:
question = input("You: ")
if question.lower() in ['exit', 'quit', 'q']:
break
response = agent.query(question)
print(f"Agent: {response}\n")
except KeyboardInterrupt:
print("\n👋 Goodbye!")
break
except Exception as e:
print(f"❌ Error: {e}\n")
if __name__ == "__main__":
main()
================================================
FILE: submissions/.gitkeep
================================================
================================================
FILE: submissions/Articles/Contributing-to-Chimoney-Hacktoberfest.md
================================================
# Contributing to Chimoney Projects: A Hacktoberfest 2024 Guide
## 1. Introduction to Hacktoberfest and Chimoney
### What is Hacktoberfest?
Hacktoberfest is an annual event that celebrates open source software and encourages meaningful contributions to open source projects. It's sponsored by DigitalOcean and runs throughout the month of October. Participants who successfully complete the challenge by making 4 valid pull requests to open source repositories are eligible for exciting rewards and recognition.
### Overview of Chimoney's Platform and API
Chimoney is a global payouts and infrastructure provider offering an API that businesses, startups, and communities can integrate to handle bulk payouts, rewards, or disbursements in multiple currencies. Chimoney enables users to send money, gift cards, airtime, and other digital assets to recipients worldwide, making it easier for organizations of all sizes, especially those with distributed teams or diverse communities, to manage payments efficiently.
#### Key features of Chimoney include:
- **Bulk payouts**: Organizations can send payments to multiple recipients at once, with recipients able to redeem in their local currencies, saving time and effort.
- **Multi-currency support**: Chimoney supports a range of currencies, including USD, CAD, and NGN, for global transactions.
- **Payment requests**: Chimoney simplifies the process of requesting and receiving payments, making it easier for users to get paid.
- **API integration**: Developers can integrate Chimoney’s API into their systems, automating payment processes and scaling effortlessly.
### Why Open-Source Contributions Matter to Chimoney
Open-source contributions are vital to Chimoney's growth and innovation. By engaging with the developer community, Chimoney can:
- Improve its platform and API based on real-world use cases and feedback
- Foster innovation through collaboration with developers worldwide
- Build a strong, supportive community around its products
- Enhance documentation and examples, making it easier for new developers to adopt Chimoney's solutions
## 2. Step-by-Step Contribution Guide
### Requirements for Contributing
Before you start contributing, make sure you have:
- A GitHub account
- Git installed on your local machine
- Node.js and npm (for running JavaScript projects)
- Basic knowledge of JavaScript, React, or relevant technologies used in Chimoney's projects
### How to Set Up the Project Locally
#### Cloning the Repository
1. Fork the Chimoney repository you want to contribute to by clicking the "Fork" button on GitHub.

2. Clone your forked repository to your local machine:

```bash
git clone https://github.com/your-username/repository-name.git
cd repository-name
```

#### Running the Project Locally
1. Install the project dependencies:
```bash
npm install
```
2. Set up any necessary environment variables (refer to the project's README for specific instructions).
3. Start the development server:
```bash
npm run dev
```
## 3. Making Your First Contribution
### How to Choose an Issue
1. Browse the issues in the Chimoney repository you're interested in.
2. Look for issues labeled `good first issue` or `help wanted` for beginner-friendly tasks.
3. Read through the issue description and comments to understand the requirements.
### Being Assigned an Issue
1. Comment on the issue expressing your interest in working on it.
2. Wait for a maintainer to assign the issue to you.
### Contributing Code or Documentation
1. Create a new branch for your contribution:
```bash
git checkout -b feature/your-feature-name
```
2. Make your changes, following the project's coding style and guidelines.
3. Test your changes thoroughly.
4. Commit your changes with a meaningful commit message:
```bash
git commit -m "Add feature: Brief description of your changes"
```
### How to Create and Submit a Pull Request (PR)
1. Push your changes to your forked repository:
```bash
git push origin feature/your-feature-name
```
2. Go to the original Chimoney repository on GitHub and click "New pull request".
3. Choose your fork and the branch containing your changes.
4. Fill out the PR template, providing a clear description of your changes.
5. Submit the pull request for review.
### Best Practices for Clean and Maintainable Code
- Follow the project's coding style and conventions.
- Write clear, concise comments and documentation.
- Keep your changes focused and avoid unrelated modifications.
- Write unit tests for new features or bug fixes when applicable.
## 4. Opportunities for Contribution
### Areas Where Chimoney Needs Contributions
- Bug fixes and performance improvements
- New features aligned with Chimoney's roadmap
- Documentation improvements and translations
- Integration examples and SDKs in various programming languages
### Creating Technical Articles or Guides
Consider writing technical articles or guides about:
- Integrating Chimoney's API into different types of applications
- Best practices for using Chimoney in specific use cases
- Tutorials on using Chimoney's features effectively
## 5. Contribution Guidelines
### Overview of Chimoney's Contribution Guidelines
- Always create an issue before submitting a pull request for new features.
- Follow the code of conduct and maintain a respectful, inclusive environment.
- Keep pull requests focused on a single issue or feature.
### How to Write Meaningful Commit Messages
- Use the imperative mood (e.g., "Add feature" instead of "Added feature")
- Keep the first line short (50 characters or less) and descriptive
- Use the body of the commit message to explain the "why" behind the changes
# Code of Conduct
Review Chimoney Community's Code of conduct [here](https://github.com/Chimoney/chimoney-community-projects/blob/main/CODE_OF_CONDUCT.md)
## 6. Benefits of Contributing
### What Contributors Gain from Hacktoberfest
- Practical experience working on real-world projects
- Networking opportunities within the open-source community
- Hacktoberfest swag (t-shirts, stickers) for qualifying participants
- Personal growth and learning new technologies
### How Contributions Impact Chimoney's Platform and Mission
Your contributions help Chimoney:
- Improve its products and services
- Reach a wider audience of developers and businesses
- Accelerate innovation in global payment solutions
- Create a more robust and reliable platform for users worldwide
## 7. Next Steps After Contribution
### Staying Involved in the Chimoney Community
- Join Chimoney's developer community on [Discord](https://discord.gg/TsyKnzT4qV)
- Attend Chimoney's events [here](https://lu.ma/Chimoney) to connect with its global community and be updated on the community initiatives.
### Opportunities for Continuous Contributions
- Consider becoming a regular contributor
- Mentor new contributors and help them get started
- Propose and lead new initiatives or features within the Chimoney ecosystem
By contributing to Chimoney's open-source projects, you're not just improving your skills and building your portfolio—you're also making a tangible impact on global financial inclusivity and innovation. We look forward to your contributions and can't wait to see what we can achieve together during Hacktoberfest 2024 and beyond!
## About the Author
### Daniel Oladepo
Daniel Oladepo is a passionate backend developer and software engineer with a strong foundation in mechanical engineering. With a keen interest in web technologies and server-side development, Daniel has contributed to various projects, from creating reusable templates to developing full-fledged messaging systems. His diverse skill set spans multiple programming languages and frameworks, making him a versatile developer capable of tackling complex challenges. Daniel's experience in both academic and professional settings demonstrates his commitment to continuous learning and innovation in the field of software development.
================================================
FILE: submissions/Articles/Flexible-payout-solutions.md
================================================

# Why Flexible Payout Solutions Matter for Marketplace and Gig Economies
There has been a continuous shift in how employers connect with the workforce and the demand for gig workers has continued to grow since the [COVID-19](https://www.forbes.com/sites/rebeccahenderson/2020/12/10/how-covid-19-has-transformed-the-gig-economy/) pandemic. [Data from the World Bank shows that gig economy accounts for up to 12% of labor force globally](https://www.worldbank.org/en/news/press-release/2023/09/07/demand-for-online-gig-work-rapidly-rising-in-developing-countries). However, finding a payment service that enables gig workers to receive payment on their terms has become a recurring challenge.
Challenges such as differences in currencies and payment systems between freelancers and employers that cause payout delays and other bottlenecks are factors why freelancers and platform owners should adopt Flexible Payout Solutions that facilitate faster payment in freelancers' preferred currencies.
## What are Flexible Payout Solutions?
Flexible payment solutions provide tailored payment systems that allow gig workers to receive money in their preferred currencies and on any payment options they choose. Simply put, it supports quick and seamless payment to workers across various countries through cryptocurrencies, bank transfers or mobile wallets, removing payment barriers like currency differences. An example of a flexible payment solution is [Chimoney’s API](https://chimoney.readme.io/reference/getting-started-with-your-api).
### The Importance of Flexible Payout Solutions
Flexible payout solutions provide a fast and real-time payout that benefits actors in the gig economy and online marketplace. It is vital to see why this solution has become a go-to option for payment. Here are factors why flexible payout solutions is a better option for handling diverse payments across countries and currencies.
**User Convenience and Satisfaction:** Offering flexible payment options such as bank transfers, digital wallets, and mobile money payment provides gig workers the flexibility to choose among the more convenient options, thereby boosting user experience.
**Seamless Currency Conversion:** By making it possible for multiple currencies to be available locally for easy conversion, flexible payout solutions enable gig workers to experience stress-free international transactions, thereby removing the challenges of local currency conversion and additional transaction fees.
**Global Reach and Inclusivity:** Flexible payout solutions handle diverse payments in user terms, allowing workers or sellers globally to receive payment in their local currencies. It also supports payments through local methods to meet the needs of global users.
**Faster Payments:** Since the gig economy operates remotely without physical contact, delay in payment could affect trust. Flexible payment solutions offer a quicker transfer like instant wallet transfers, helping gig workers to receive payment as at when due.
## Overview of Marketplace and Gig Economies
A marketplace is an online platform that connects third-party sellers and buyers and helps facilitate buying and selling. It's an intermediary that helps buyers find sellers who advertise their products and services. A marketplace provides the platform for a gig economy to thrive by easily connecting gig employers to gig workers. You may be wondering what the gig economy means. Simply put, the gig economy is temporary work that provides a short-term position to freelancers who work independently. The gig economy guarantees flexibility as the workers can work remotely without being confined in a space.
### Actors Driving Marketplace and Gig Economies
The two key actors that drive the marketplace and gig economies are the employer and the gig worker. They complement each other by offering value in reward and services. Here are the two key actors:
**The Gig Employer:**
An employer in a marketplace and gig economy refers to a person or business that offers employment to a gig worker for a service or product and rewards the worker for their service.
**The Gig Worker:**
Gig workers offer extensive services or products to an employer on a temporal or contract basis to get a monetary reward at the end of their task.
### Challenges Faced by Gig Economy Workers and Marketplace Sellers
The gig economy workers and marketplace sellers often experience underlying challenges that affect revenue generation and overall user experience.
Here are some of the challenges they face:
- Currency Disparities: A huge concern for gig economy workers and marketplace sellers is how they could convert the currencies they receive to their local currencies without incurring extra charges. The exchange rate changes during conversion, and the additional charges could affect earnings.
- Delayed Payments: Delay in payment is a common experience for gig economy workers and marketplace sellers. This delay in cross-border transactions is frustrating for users and could affect trust.
- Limited Payment Methods: Workers in the gig economy cut across various countries with unique means of receiving payment. Many platforms only have limited payout options, which may not be accessible to users.
- Lack of Transparency: There are incidents where workers and sellers lose a large chunk of their earnings due to hidden fees during payout. Some platforms also fail to handle chargebacks and refunds efficiently.
## How Chimoney’s API Addresses These Issues
Chimoney’s API enables flexibility in payment structure and offers a wide variety of services to over 100 countries on a single Platform and API. Here is how Chimoney’s API addresses challenges faced by gig economy workers and marketplace sellers.
- Multiple Currencies Options: Once you sign up with [Chimoney’s API](https://chimoney.readme.io/reference/getting-started-with-your-api), you can integrate multiple currency payout options, including gift cards and cryptocurrencies. The [API](https://chimoney.readme.io/reference/getting-started-with-your-api) endpoints allow you to initiate a transaction from a Chimney wallet to a recipient's preferred local currency.
- Multiple Payout Methods: [Chimoney](https://chimoney.io/) provides multiple payout options, such as [Payout Chimoney, Payout Mobile Money, Payout Bank, Payout Giftcard](https://chimoney.readme.io/reference/getting-started-with-your-api#payout-mobile-money) and more. By integrating [Chimoney’s API](https://chimoney.readme.io/reference/getting-started-with-your-api), developers or platform owners can initiate transactions from its multi-currency wallet to a receiver payment option.
- Cross-border Payouts: [Chimoney’s API](https://chimoney.readme.io/reference/getting-started-with-your-api) eliminates cross-border payment complexities by providing seamless payment solutions, multi-currency, and allowing payment across various countries. It supports local compliance with regulators and helps platform owners achieve global reach.
- Secured and Transparency: Every transaction carried out when using [Chimoney’s API](https://chimoney.readme.io/reference/getting-started-with-your-api) is fast and secure. The payment process is simple and detailed, with transactions done swiftly, empowering users to control their cash flow and payment history. There are no hidden fees during the transaction.
- Ease of integration: [Chimoney’s API](https://chimoney.readme.io/reference/getting-started-with-your-api) offers a flexible API that developers can easily integrate with, launch and scale payment solutions. It also provides robust services that can integrate into any marketplace platform irrespective of the tech stack.
## Conclusion
Chimoney’s API provides wholesome and seamless cross-border payout solutions. It guarantees instant, secured and simplified payment options for workers in over 100 countries. Whether you are a [developer](https://dash.chimoney.io/auth/signin?next=/developers), a platform owner, or a gig worker, with [Chimoney’s API](https://chimoney.readme.io/reference/getting-started-with-your-api), your payout and disbursement needs are well covered. [Get started now](https://chimoney.readme.io/reference/getting-started-with-your-api).
## About the Author
**Chukwuemeka Abuba**
A technical writer and frontend developer specializing in TypeScript and Next.js. Passionate about crafting clear documentation, building user-centric interfaces, and sharing knowledge with the developer community.
================================================
FILE: submissions/Articles/GlobalPayoutGuide.md
================================================
# How to Choose the Right API for Global Payouts: A Developer's Guide
As businesses expand globally, developers must choose the right payout API to facilitate secure, seamless, and scalable financial operations. Whether you're sending payments to international employees, rewarding users with gift cards, or transferring funds via mobile money, the right API can make the difference between a smooth or painful experience. This guide will help you navigate the key factors when selecting a global payout API, compare leading solutions, and spotlight **Chimoney's API** as a standout option.
## Key Factors to Consider When Choosing a Payout API
When evaluating a payout API, developers should focus on several essential factors to ensure the best fit for their business needs:
### 1. **Security**
Security is the backbone of any financial transaction system, and handling global payouts is no exception. Look for APIs that adhere to industry-standard security protocols, such as encryption, secure tokenization, and multi-factor authentication (MFA). These practices ensure that sensitive data, like personal information and financial details, are protected against breaches.
### 2. **Ease of Integration**
An API's usability can make or break a developer's experience. A well-documented API with simple, intuitive endpoints and easy-to-follow examples will save time and reduce the chances of errors. Tools such as SDKs, libraries, and clear onboarding documentation enhance the integration process, allowing developers to get up and running quickly.
### 3. **Global and Multi-Currency Support**
Global payout systems must cater to various regions and currencies. Consider whether the API supports multiple currencies, international payment methods (e.g., bank transfers, mobile money, gift cards), and can handle different compliance requirements for countries worldwide. The more expansive the reach, the better suited the API will be for businesses with global operations.
### 4. **Scalability**
Your payout needs today may not be the same a year from now. An API that scales with your business, supporting high transaction volumes without performance degradation, is crucial for growing companies.
### 5. **Flexibility**
The flexibility of an API is often measured by the variety of payout methods it supports, and whether it allows for customization. An ideal API would let businesses send payouts via multiple channels like bank transfers, mobile money, airtime, or gift cards, giving users flexibility in receiving payments.
### 6. **Cost-Effectiveness**
Look for APIs with transparent pricing structures that align with your budget. It's important to account for transaction fees, currency conversion costs, and any hidden charges that may apply. Ensure that the payout API offers a cost-effective solution for your business's needs.
---
## Comparing Chimoney’s API to Other Global Payout Solutions
### **Chimoney API**
Chimoney provides a comprehensive global payout API that offers unmatched flexibility for developers and businesses. It allows companies to send various types of payouts, including mobile money, bank transfers, airtime, and gift cards, across more than 130 countries.
- **Ease of Integration:** Chimoney offers well-documented endpoints and example use cases to simplify integration. Developers can quickly get started with Chimoney’s API and scale their solution as needed.
- **Security:** Chimoney's API is designed with stringent security measures, ensuring secure transactions with encryption and compliance with global payment standards.
- **Global Support:** Chimoney excels in global coverage, supporting multiple payment methods across more than 130 countries, making it a versatile solution for businesses operating internationally.
- **Scalability:** Chimoney is built to handle high transaction volumes, making it a reliable option for businesses that anticipate significant growth.
- **Flexibility:** From bank transfers to mobile money and airtime rewards, Chimoney offers diverse payout options, ensuring that users can receive payments in their preferred method.
### **Other Global Payout Solutions**
While there are many payout APIs in the market, Chimoney's flexibility and global reach make it stand out. However, here’s how some other solutions compare:
- **[PayPal](https://chimoney.io/using/paypal/for-sending/mass-payments/vs-using/chimoney/)** offers global payouts, but primarily focuses on traditional payment methods like bank transfers and digital wallets, lacking support for mobile money and airtime.
- **[Wise](https://chimoney.io/using/wise/for-sending/cross-border-payout/vs-using/chimoney/)** (formerly TransferWise) specializes in low-cost international money transfers, but doesn’t offer gift cards or mobile money payouts.
- **[Payoneer](https://chimoney.io/using/payoneer/for-sending/contractor-payments/vs-using/chimoney/)** supports global payments, but its focus is more on freelancer payments and business-to-business (B2B) transfers, limiting its payout method variety.
---
## Chimoney API: A Unique Solution for Global Payouts
What makes Chimoney particularly special is the variety of payout methods it supports and its global reach. Here's an overview of what Chimoney offers:
### 1. **Payout Chimoney**
Chimoney's API allows businesses to send flexible rewards (Chimoney) that can be exchanged for various services, such as airtime, mobile money, gift cards, and more. This gives businesses the freedom to offer diverse rewards that cater to user preferences.
- [Payout Chimoney API Documentation](https://chimoney.readme.io/reference/post_v0-2-payouts-chimoney-1)
### 2. **Mobile Money Payouts**
Chimoney supports **mobile money payouts** in over 10 countries, making it easier to send payments to regions where mobile money is a popular payment method. This is particularly useful for businesses operating in parts of Africa and Southeast Asia.
- [Payout Mobile Money API Documentation](https://chimoney.readme.io/reference/post_v0-2-payouts-mobile-money-1)
- [Supported Mobile Money Countries](https://chimoney.readme.io/reference/get_v0-2-info-mobile-money-codes-1)
### 3. **Airtime Payouts**
Chimoney allows businesses to send **airtime payouts** across 10+ countries. This feature is ideal for companies that want to reward users with mobile prepaid credit, a common payment method in emerging markets.
- [Payout Airtime API Documentation](https://chimoney.readme.io/reference/post_v0-2-payouts-airtime-1)
- [Supported Airtime Countries](https://chimoney.readme.io/reference/get_v0-2-info-airtime-countries-1)
### 4. **Bank Payouts**
With support for bank transfers in over **130 countries**, Chimoney makes it simple for businesses to send funds directly to users' bank accounts. This ensures that users in countries with strong banking infrastructures can receive payments seamlessly.
- [Payout Bank API Documentation](https://chimoney.readme.io/reference/post_v0-2-payouts-bank-1)
- [Supported Bank Countries](https://chimoney.readme.io/reference/get_v0-2-info-country-banks-1)
### 5. **Gift Card Payouts**
Chimoney offers **gift card payouts** in over 20 countries, with more than 200 gift card options. This is a great solution for businesses looking to reward users with popular gift card options in various regions.
- [Payout Gift Card API Documentation](https://chimoney.readme.io/reference/post_v0-2-payouts-gift-card-1)
### 6. **Interledger Payment Pointers for Web Monetization**
Chimoney supports **Interledger Payment Pointers for Web Monetization**, enabling businesses to leverage blockchain technology for fast and secure payouts. This feature provides an innovative way to handle digital asset transactions on a global scale.
- [Payout API Documentation](https://chimoney.readme.io/reference/post_v0-2-payouts-initiate-chimoney-1)
---
## To get started with the Chimoney API, follow this process:
- **Get Sandbox Access**:
Before integrating Chimoney's Global Payouts API into your live environment, start by accessing the **Sandbox** environment. This allows you to safely test your payment solutions in a simulated setting, ensuring everything runs smoothly without affecting real transactions. You can [Get Sandbox Access here](https://chimoney.readme.io/reference/sandbox-environment) and begin experimenting with API calls right away.
- **Test Your Integration**:
Once you've set up your API in the sandbox environment, it's time to test. Run through various payment scenarios, simulate real transactions, and confirm that your integration meets your business requirements. Thoroughly testing in the sandbox ensures your payment infrastructure is robust and error-free before going live.
- **Go Live!**:
After successful testing in the sandbox environment, you're ready to launch your payment system in the live environment. Switching to live mode is straightforward and enables real transactions, allowing you to harness the full power of Chimoney’s Global Payouts API for seamless global payments. Ensure that you have completed all checks before flipping the switch to provide your users with an uninterrupted payment experience.
## Conclusion
Choosing the right payout API depends on several factors, such as security, ease of integration, and global support. Chimoney’s API offers a robust solution for businesses that need flexible, secure, and scalable payouts across multiple methods and countries. With support for mobile money, airtime, gift cards, bank transfers, and even XRPL payments, Chimoney stands out as a reliable and versatile choice for global payouts.
Interested in learning more about how the Chimoney API can streamline your payouts? Book a [demo session](https://chimoney.io/?book_a_demo=1) with us today.
================================================
FILE: submissions/Articles/Quickstart_Guide.md
================================================
# Quickstart Guide to Integrate Chimoney API
Welcome to the Chimoney Quickstart Guide! This guide will help you easily integrate the Chimoney API into your applications.
## Step 1: API Key Generation
To start using the Chimoney API, you need to sign up and generate an API key from the developer dashboard:
1. Go to the [Chimoney Developer Dashboard](https://dash.chimoney.io/auth/signin?next=/).
2. Sign up for an account or log in if you already have one.
3. Navigate to the "API Keys" section.
4. Click on "Generate New API Key" and save your key securely.
## Step 2: SDK Installation
Chimoney provides SDKs for popular programming languages to simplify integration. Below are instructions for installing the SDK for Node.js and Python.
### Node.js
To install the Chimoney SDK for Node.js, use npm:
```bash
npm install chimoney-sdk
```
### Python
To install the Chimoney SDK for Python, use pip:
```bash
pip install chimoney-sdk
```
## Step 3: Making a Sample Request
Here’s how to make a basic API call to initiate a payout using the Chimoney SDK.
### Node.js Example
```javascript
const Chimoney = require('chimoney-sdk');
const chimoney = new Chimoney('YOUR_API_KEY');
chimoney.payout({
amount: 100,
currency: 'USD',
recipient: 'recipient@example.com',
})
.then(response => {
console.log('Payout successful:', response);
})
.catch(error => {
console.error('Error initiating payout:', error);
});
```
### Python Example
```python
from chimoney import Chimoney
chimoney = Chimoney(api_key='YOUR_API_KEY')
response = chimoney.payout(amount=100, currency='USD', recipient='recipient@example.com')
print('Payout successful:', response)
```
## Step 4: Overview of Key Features
The Chimoney API provides several key functionalities, including:
- **Payouts**: With Chimoney’s API, you can initiate seamless payouts to over 130 countries via bank, mobile money, airtime, or even Interledger-enabled accounts.
- **Multi-Currency Wallets**: Manage balances in multiple currencies, enabling smooth cross-border payments and better control over currency exchanges.
- **Payment Requests**: Request payments from customers or clients, making invoicing and collections easier with a streamlined API integration.
- **Redemption of Value**: Offer users the ability to redeem Chimoney through options such as bank transfers, Mobile Money, gift cards, or airtime.
For more detailed information, please refer to the [API Documentation](https://chimoney.io/developers-api/).
---
## Libraries & Plugins
Chimoney offers pre-written code packages (server-side helper libraries) to make using the API easier! Below are links to some popular SDKs available in the Chimoney community:
- **Python SDK**: [Chimoney-Python](https://github.com/Chimoney/chimoney-community-projects/tree/main/submissions/Chimoney-Python)
- **PHP-Laravel SDK**: [Chiconnect Laravel Web App](https://github.com/Chimoney/chimoney-community-projects/tree/main/submissions/chiconnect-laravel-web-app)
- **JavaScript (NPM)**: [Chimoney-JS](https://github.com/Chimoney/chimoney-community-projects/tree/main/submissions/chimoney-js)
- **Flutter SDK**: [Chispend Widget](https://github.com/Chimoney/chimoney-community-projects/tree/main/submissions/chispend_widget)
## Use Cases
Here are a few implementations of the Chimoney API built and maintained by our Chimoney Community:
- **Instant Airtime Redemption Page**: [Redeem Airtime](https://github.com/Chimoney/chimoney-community-projects/tree/main/submissions/chimoney-redeem-airtime)
- **Payout using Chimoney Twitter Bot**: [Chisend](https://github.com/Chimoney/chimoney-community-projects/tree/main/submissions/Chisend)
- **Payout Gift Card**: [Gift Card Payout](https://github.com/Chimoney/chimoney-community-projects/tree/main/submissions/chiconnect-giftcard-payout)
- **Mobile Money Payout**: [Mobile Money Payout](https://github.com/Chimoney/chimoney-community-projects/tree/main/submissions/chiconnect-mobile-money-payout)
- **Bank Payout**: [Bank API Payout](https://github.com/Chimoney/chimoney-community-projects/tree/main/submissions/chiconnect-bank-api-payoutt)
- **Paypaddy**: [Paypaddy](https://github.com/Chimoney/chimoney-community-projects/tree/main/submissions/pay-paddy)
- **Secret Santa**: [Secret Santa](https://github.com/Chimoney/chimoney-community-projects/tree/main/submissions/secret-santa)
- **Chimap**: [Chimap](https://github.com/Chimoney/chimoney-community-projects/tree/main/submissions/chimap)
For more examples and resources, visit the [Chimoney Community Projects](https://github.com/Chimoney/chimoney-community-projects).
## Author
# I’m Brijesh Thummar, a second-year Computer Science student (Class of 2027) and aspiring Quant Developer. I love coding, solving complex problems, and building innovative software solutions. Let’s connect and create something impactful
================================================
FILE: submissions/Articles/README.md
================================================
# Articles
This folder contains all articles written and submitted by our open-source contributors. Each article here highlights unique perspectives, use cases, and technical insights related to Chimoney's platform, API and services.
## How to Submit
- Create a markdown for your submission (e.g., `article-title.md`).
- Use a descriptive file name, such as `optimizing-chimoney-integration.md`.
- Include your name and a brief bio at the end of your article.
- Add your article within this `Articles` folder.
- Create a Pull Request to submit your article for review
================================================
FILE: submissions/Articles/Update-Authentication-page.md
================================================
# Authentication
This guide explains how to authenticate your requests to the Chimoney API. Follow these steps to get started with integrating Chimoney's payment solutions into your applications.
## Getting Started
### For Businesses
1. **Create an Account**
- Sign up at [dash.chimoney.io](https://dash.chimoney.io)
- Complete the registration process
2. **Request API Access**
- Email support@chimoney.io to request "Verification and API Access"
- Include:
- Links to your website
- Description of your use case
- Alternatively, you can [book a demo](https://chimoney.io/book-a-demo/)
3. **Choose a Plan**
- Review available plans at [chimoney.io/pricing](https://chimoney.io/pricing/)
- Select an appropriate subscription tier
- Complete the payment process
### For Developers (Testing)
If you're just testing the API, you can use our sandbox environment. Visit our [Sandbox Environment Guide](https://chimoney.readme.io/reference/sandbox-environment) to get started.
## API Key Authentication
### Obtaining Your API Key
Once your account is approved, you can find your API key in the Chimoney developer dashboard. Two types of keys are provided:
- **Test API Key**: For development and testing
- **Live API Key**: For production use
### Using Your API Key
Include your API key in the `Authorization` header of all requests:
```bash
# Example curl request
curl -X POST https://api.chimoney.io/v0.2/payment/initiate \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"amount": 100,
"currency": "USD"
}'
```
### Sample Response
```json
{
"status": 200,
"data": {
"id": "pay_123xyz",
"status": "pending"
}
}
```
## Security Best Practices
1. **Protect Your API Keys**
- Never expose API keys in client-side code
- Store keys in environment variables
- Don't commit API keys to version control
2. **Key Management**
- Rotate API keys periodically
- Use different keys for development and production
- Revoke compromised keys immediately
3. **Environment Variables Example**
```bash
# .env file
CHIMONEY_API_KEY=your_api_key_here
```
## Error Handling
### Common Authentication Errors
1. **401 Unauthorized**
```json
{
"status": 401,
"error": "Invalid API key provided"
}
```
*Solution*: Verify your API key is correct and properly formatted in the Authorization header
2. **403 Forbidden**
```json
{
"status": 403,
"error": "Insufficient permissions"
}
```
*Solution*: Ensure your account has the necessary permissions for the requested operation
## Code Examples
### Node.js
```javascript
const axios = require('axios');
const chimoneyAPI = axios.create({
baseURL: 'https://api.chimoney.io/v0.2/',
headers: {
'Authorization': `Bearer ${process.env.CHIMONEY_API_KEY}`,
'Content-Type': 'application/json'
}
});
async function initiatePayment() {
try {
const response = await chimoneyAPI.post('/payment/initiate', {
amount: 100,
currency: 'USD'
});
console.log(response.data);
} catch (error) {
console.error('Authentication error:', error.response.data);
}
}
```
### Python
```python
import requests
import os
CHIMONEY_API_KEY = os.getenv('CHIMONEY_API_KEY')
headers = {
'Authorization': f'Bearer {CHIMONEY_API_KEY}',
'Content-Type': 'application/json'
}
def initiate_payment():
try:
response = requests.post(
'https://api.chimoney.io/v0.2/payment/initiate',
headers=headers,
json={
'amount': 100,
'currency': 'USD'
}
)
return response.json()
except requests.exceptions.RequestException as e:
print(f"Authentication error: {e}")
```
## Additional Resources
- [API Reference](https://chimoney.readme.io/reference/knowing-the-api)
- [Sandbox Environment](https://chimoney.readme.io/reference/sandbox-environment)
- [Pricing Plans](https://chimoney.io/pricing/)
- [Book a Demo](https://chimoney.io/book-a-demo/)
For additional support or questions, contact support@chimoney.io
================================================
FILE: submissions/Articles/chimoney-global-data-annotators.md
================================================
# The Future of Payments for AI Workforce: Why Chimoney is the Perfect Solution for Paying Global Data Annotators
Artificial intelligence (AI) companies rely on large volumes of carefully labeled data to train their systems, and much of this work is done by a global workforce of data annotators. As the AI industry grows, so does the need for an efficient, reliable way to compensate annotators from various countries. Managing payments across borders comes with its own set of challenges, including different currencies, payout methods, and local regulations. This is where **Chimoney** provides an invaluable solution—enabling AI companies to handle global payments quickly and securely.
---
## The Role of Data Annotation in AI Development
AI models require vast amounts of annotated data to function properly. Data annotators play a critical role in preparing this data by labeling images, videos, text, and other content. As demand for AI-driven applications continues to grow, so does the need for a highly skilled, distributed workforce to handle data annotation.
Given the global nature of the workforce, AI companies often hire annotators from different countries, each with unique payment preferences and systems. Efficiently managing these payments is crucial to ensure timely compensation and continued worker satisfaction.
---
## Challenges of Paying Global Data Annotators
AI companies face several common challenges when compensating their global workforce:
1. **Currency Exchange and Fees**: Managing payouts across various currencies means dealing with fluctuating exchange rates and conversion fees, which can lead to additional costs for both the company and the annotators.
2. **Slow Payment Processes**: Traditional international bank transfers are often slow, taking days or even weeks to clear. These delays can frustrate annotators and harm the company's ability to retain talent.
3. **Diverse Payout Preferences**: Some workers prefer bank transfers, while others rely on mobile money, digital wallets, or even cryptocurrency. Offering limited payment options can reduce a company’s appeal in certain regions.
4. **International Compliance and Regulations**: Each country has its own set of financial regulations, including anti-money laundering (AML) and know-your-customer (KYC) requirements. AI companies must ensure compliance with these laws to avoid legal complications, which can be a complex and time-consuming process.
---
## How Chimoney Simplifies Payments for AI Companies
Chimoney’s API is specifically designed to tackle these global payment challenges. With Chimoney, AI companies can streamline payouts, ensuring fast, secure, and compliant payments to annotators across the world.
### 1. Support for Multiple Currencies and Payout Methods
Chimoney’s API allows AI companies to pay annotators in their local currency, saving both parties from high conversion fees and ensuring prompt payments. Chimoney supports an extensive range of currencies and payout methods, including:
- **Currencies**: USD, EUR, GBP, CAD, INR, NGN, GHS, KES, ZAR, and more.
- **Payout Methods**: Bank transfers, mobile money (such as M-Pesa), digital wallets (like PayPal and Venmo), cryptocurrency (Bitcoin, Ethereum), and gift cards.
By offering these flexible options, Chimoney ensures that data annotators, regardless of their location, can receive payments in the most convenient way for them.
### 2. Faster Payment Processing
With Chimoney’s API, AI companies can automate their payment process, significantly reducing the time it takes to compensate annotators. Traditional payment methods often result in lengthy delays, but Chimoney guarantees fast and secure transactions across borders.
Prompt payments lead to happier workers, allowing AI companies to maintain an engaged and reliable workforce, which is critical for projects with tight deadlines.
### 3. Simplified Compliance
Managing international compliance is one of the most challenging aspects of paying global workers. Chimoney simplifies this by ensuring compliance with international financial regulations, including AML, KYC, and local financial reporting laws. Chimoney’s API helps AI companies navigate this complex landscape by automating compliance procedures, reducing the administrative burden, and helping companies stay compliant with the relevant regulations in each country.
By streamlining both tax and regulatory compliance, Chimoney allows AI companies to focus on growing their business without getting bogged down by complex legal requirements.
### 4. Scalability for Growing Teams
Chimoney’s API is built to scale alongside your AI company’s growing workforce. Whether you’re managing payments for a handful of annotators or thousands of workers worldwide, Chimoney can handle the volume of transactions efficiently and securely. As your workforce grows, Chimoney grows with you, providing a seamless payout experience for all team members.
---
## Integrating Chimoney’s API: A Seamless Solution
Chimoney’s API is designed for easy integration, making it simple for developers and AI platforms to implement global payout solutions without overhauling their systems. Here’s how to get started:
### Step 1: Access Chimoney API Documentation
Visit Chimoney’s [API documentation](https://chimoney.io/) for step-by-step instructions. The documentation includes detailed guides and code samples that help developers integrate Chimoney into any platform.
### Step 2: Set Up an API Key
Create your API key for secure authentication. This key allows your platform to securely communicate with Chimoney’s services, ensuring that all payout requests are processed safely.
### Step 3: Configure Payout Methods
Choose the currencies and payout methods that best fit your global workforce. Chimoney supports a wide variety of payout options, including local currencies and alternative payment methods like mobile money, digital wallets, and cryptocurrency.
### Step 4: Automate Payouts
Automate payouts by setting triggers based on task completion or other custom logic. Chimoney’s API enables fully automated, timely payments with minimal manual intervention.
### Step 5: Test and Launch
Before going live, use Chimoney’s sandbox environment to test the integration. Once the tests are successful, launch your platform and enjoy streamlined global payouts.
---
## Why Chimoney is the Perfect Fit for AI Companies
For AI companies relying on a global workforce of data annotators, managing cross-border payments is a complex and often inefficient process. Chimoney offers a reliable, scalable solution to these challenges, supporting multiple currencies, offering diverse payout methods, and ensuring compliance with international regulations.
By integrating Chimoney’s API, AI companies can reduce payment delays, save on conversion fees, and meet the diverse needs of their annotators across the world. The result? A more satisfied workforce and a smoother, faster payment process that benefits both the company and its workers.
---
**Ready to experience seamless payouts to data annotators globally?** [Book a session](https://chimoney.io/) with Chimoney today!
### A bit about me:
I am [Adarsh](https://www.github.com/adarsh-jha-dev), a 3rd year CS undergraduate and a full-stack developer from India with some interest in technical writing as well.
================================================
FILE: submissions/Articles/global-payouts-non-profits.md
================================================
# How Global Payout Platforms Can Empower Communities and Non-profits
You’re hosting a charity baking event, raising funds to help an underserved community overseas gain access to 24/7 electricity and clean water. After reaching your monetary goal, you send the money using a platform like PayPal, feeling accomplished. But a few days later, when you check for updates, there's no clear sign that the funds have reached the community. The excitement of making a difference turns into frustration and uncertainty. A possible solution to this issue is using Chimoney. The platform allows global payouts to 130+ countries via the recipient's email and in this case the community you're sending to will be able to redeem the received payment to their own registered bank account, or mobile money instantly depending on their location. This article explores how global payout platforms can empower non-profits and community initiatives, using Chimoney as a solution to streamlining international transfers.
## How Global Payout Platforms Offer Transparency and Save You Money
Non-profits often face a common challenge when using traditional banking to send funds overseas: these platforms typically charge high fees for transactions and require additional payments to access many of their services. For example, [just last year alone, nonprofits collectively spent approximately $3 billion on transaction fees.](https://www.zeffy.com/blog/nonprofits-paid-2-billion-in-transaction-fees-last-year). In other words, traditional banking platforms can be prohibitively expensive. Unlike traditional banks, Chimoney offers transparent and affordable payment rates, with clearly disclosed fees, making it easier for nonprofits to plan and budget their funding effectively. The platform was founded by [Uchi Uchibeke, who experienced firsthand the high fees of traditional banking while trying to send prize money to winners of AfriHacks, a hackathon he was hosting.](https://chimoney.io/blogs/techstars-backs-chimoney-to-revolutionize-global-payouts/) With Chimoney, he was able to pay the winners without hidden fees. And transparent fees are just one way that global payouts can empower your nonprofit or community initiative. Let’s explore another advantage.
## Overcome Geographical Barriers with Global Payout Platforms
Another common issue that nonprofits and community initiatives face when it comes to sending funds overseas is restrictions that limit them to certain countries. This limitation can be especially challenging for organizations whose mission is to provide aid to those in need, regardless of location. Unlike traditional banks, global payout platforms like [Chimoney enable transactions in over 130 countries worldwide](https://chimoney.io/payouts/), giving nonprofits the freedom to support their intended recipients wherever they are. With this capability, nonprofits can overcome geographical barriers and better fulfill their mission.
## How Global Payout Platforms Can Make Your Transactions Quick
It may sound cliché, but "time is money" truly applies when it comes to getting funds where they’re needed—on time. Unfortunately, traditional banks often have limited transfer windows, especially for international transactions, as they [must follow country-specific protocols](https://tipalti.com/resources/learn/global-payouts/#the-challenges-that-face-global-payouts). For instance, Bank of America customers who need to send international transfers can only do so [by 5:00 pm Eastern Time](https://www.bankofamerica.com/help/cutoff-times/), and they [must use SWIFT codes](https://info.bankofamerica.com/en/digital-banking/wire-transfers), which can add [delays to the process](https://meestpay.com/what-is-swift-money-transfer-and-its-disadvantages/). These restrictions can hinder nonprofits by delaying the vital funds needed for their communities.
Global payout platforms like Chimoney offer fast delivery and 24/7 payment processing, allowing nonprofits to make quick, reliable transfers across borders. This means no waiting for banking hours or dealing with restrictive protocols—funds reach recipients quickly. For example, [AfricaHacks uses Chimoney's bulk payout feature to reward hackathon winners](https://chimoney.io/blogs/5-types-of-people-who-should-use-chimoneys-bulk-gift-cards-feature/). With just one click, all winners receive their payouts instantly, redeemable via bank transfers, mobile money, airtime, or gift cards.
Now, before you go, there’s just one more benefit of using global payout platforms like Chimoney for nonprofit funding.
## How Global Payout Platforms Can Give You Multiple Ways To Send Money
Even though traditional banks provide ways to send money, their options are often limited. For instance, [Bank of America only allows users to send money internationally via its website or mobile app](https://info.bankofamerica.com/en/digital-banking/wire-transfers), while some local banks require in-person visits. This setup can be a challenge for nonprofits, as the communities they serve may lack access to these specific channels or may not have these banks in their country.
In contrast, global payout platforms like Chimoney offer a wider range of transfer methods, allowing nonprofits to choose the delivery method that best meets the needs of their organization and recipients. For example, through Chimoney’s partnership with the [International Student Identity Card (ISIC), students can manage their finances more easily](https://chimoney.io/blogs/chimoney-partners-with-isic-to-expand-global-benefits-for-chimoney-app-users/) and send or receive funds through email, or within Chimoney app.
Now that you know the advantages of global payout systems, let’s explore how Chimoney's platform can further empower nonprofits and communities.
## How Chimoney Empowers Communities and Non-profits
Before spending time searching for global payout platforms, consider Chimoney. Chimoney simplifies payments for non-profits, helping them receive donations from around the world through Chimoney wallets. With [TryOpenGiving](https://tryopengiving.com/), an open-source platform developed by Chimoney, non-profits can accept donations via Chimoney, Interledger, and other payment methods, making financial contributions seamless and accessible for both donors and organizations.
## Now It's Your Turn
Timely financial support and transparency are essential for empowering non-profits and community initiatives to drive meaningful change. With the right global payout solution, you can enhance your impact, ensuring funds reach the people who need them most. Take the first step toward transforming your community and discover how Chimoney can unlock new possibilities.
## About the Author
Christine Belzie is a technical writer and open source maintainer. Her articles have been featured on websites like FreeCodeCamp and Pieces For Developers. If you want to connect with her, check out her socials on [Linktree](https://linktr.ee/ChrissyCodes).
================================================
FILE: submissions/Articles/payout-digital-marketplaces.md
================================================
# A Chimoney Guide to Payouts for Digital Marketplaces
Welcome to the Chimoney guide on payouts for digital marketplaces! If you run a platform that connects buyers and sellers, you know how important it is to handle payments smoothly. This guide will explain how Chimoney can help you make payouts easy and reliable for your users.
---
## Why Payouts Matter for Digital Marketplaces
Payouts ensure that sellers, freelancers, or service providers are paid accurately and on time. Delays or issues with payments can damage trust and impact the growth of your platform. A smooth payout system means vendors stay engaged, and your business operates seamlessly.
---
## Common Payout Challenges for Marketplaces
Managing payouts on a global scale isn’t without its challenges. Some of the most common issues include:
1. **Currency and Exchange Rates**: Users in different countries often need payouts in their local currencies. Converting currencies can result in poor exchange rates and fees, making the payout less valuable for your users.
2. **Regulation and compliance:** Each country has unique financial laws, such as anti-money laundering (AML) regulations, data privacy rules, and tax requirements, which businesses must follow to process payouts legally.
3. **Payment Preferences**: Different regions favor different payment methods. Offering limited payout options might alienate users from certain areas, making your platform less appealing globally.
4. **Delayed Payments**: International payments can take days or even weeks to process. This delay frustrates users and can make your marketplace less competitive.
---
## How Chimoney’s API Simplifies Global Payouts
Chimoney’s API is designed to solve the complex challenges of handling global payouts. Here’s how Chimoney can make things easier for your marketplace:
### 1. Multiple Currencies and Payout Methods
Chimoney’s API supports a variety of currencies and payout methods, including bank transfers, mobile money, digital wallets and gift cards. This flexibility allows you to cater to users worldwide, ensuring they get paid in their preferred currency and method.
### 2. Regulatory Compliance
Chimoney's API is designed with compliance in mind, ensuring that all transactions adhere to the regulatory requirements of each country involved.
### 3. Faster Payouts with Automation
By integrating Chimoney’s API, you can offer faster payouts with less manual work. The API automates payment processing, reducing delays and ensuring users are paid quickly, no matter where they are.
### 4. Scalable Payment Infrastructure
Chimoney’s API is designed to grow with your platform. Whether you’re handling payments for a few users or thousands, the API’s scalable infrastructure ensures smooth and efficient payouts, even as your marketplace expands.
---
## How to Integrate Chimoney’s API into Your Marketplace
Integrating Chimoney’s API is a straightforward process. Follow these steps to get started:
### Step 1: Access Chimoney’s API Documentation
Visit the [Chimoney API Documentation](https://chimoney.readme.io/reference/getting-started-with-your-api) to get all the resources you need. The documentation offers step-by-step instructions and code samples to help developers integrate the API seamlessly.
### Step 2: Get Your API Key
Create an API key to authenticate your marketplace.
### Step 3: Configure Payout Options
Customize the payout options available on your platform to best suit your user base. Chimoney offers allows you to support multiple currencies (USD, CAD, NGN) and different payment methods such as bank, Mobile Money, [Interac](https://chimoney.io/blogs/interac-e-transfer-bulk-for-canadian-businesses-integration-and-api/), Airtime and Gift cards
### Step 4: Automate Payouts
Use Chimoney’s API to automate your payout process. For instance, you can trigger automatic payouts after a sale is completed or a service is approved, ensuring users get paid without any delays.
### Step 5: Test Your Integration
Use Chimoney’s sandbox environment to test your integration before going live. Ensure all payment methods and currencies are working correctly to avoid any disruptions for your users.
### Step 6: Go Live
Once everything is tested, launch the integration. Chimoney’s reliable infrastructure ensures smooth operation, even as your platform grows globally.
---
## Example Code: Making a Payout Request
Here’s a simple code sample demonstrating how to make a payout request using Chimoney’s API:
```javascript
const axios = require("axios");
const options = {
method: "POST",
url: "https://api.chimoney.io/v0.2/payouts/bank",
headers: {
accept: "application/json",
"content-type": "application/json",
Authorization: "Bearer YOUR_API_KEY", // Replace with your actual API key
},
data: {
subAccount: "yourSubAccountID", // Optional: Wallet account to payout from
turnOffNotification: false, // Optional: set to true to disable notifications
debitCurrency: "USD", // Currency to debit from
banks: [
{
countryToSend: "NG", // Payout country
account_bank: "044", // Bank code
account_number: "1234567890", // Recipient account number
valueInUSD: 100, // Payout value in USD
amount: 100, // Payout amount in specified currency
reference: "txn123456", // Unique transaction reference
fullname: "John Doe", // Full name of the beneficiary
branch_code: "", // Optional: Required for some countries, not Nigeria
narration: "Payout for services", // Description for the user
collectionPaymentIssueID: "issue123", // Optional: Issue ID for payment
},
],
},
};
axios
.request(options)
.then(function (response) {
console.log(response.data);
})
.catch(function (error) {
console.error(error);
});
```
This code sends a payout request for $100 USD to a recipient's bank account using Chimoney's API.
---
## Why Chimoney Is the Right Choice for Your Marketplace
Digital marketplaces need flexible and reliable payout systems to thrive and Chimoney’s API provides the tools you need to handle multiple currencies, offering various payout methods, and ensuring faster payments — all while simplifying compliance and scaling with your platform’s growth.
---
## Get Started with Chimoney Today
Ready to make payouts easier? Visit the [Chimoney API Documentation](https://chimoney.readme.io/reference/getting-started-with-your-api) to learn more and start building an efficient payout solution for your marketplace.
---
## About Me
I am [Adarsh](https://www.github.com/adarsh-jha-dev), a 3rd year CS undergraduate and full-stack developer from India.
================================================
FILE: submissions/Articles/tutorial_on_sending_p2p_Interledger _payments.md
================================================
# Tutorial: Integrating Chimoney's Payment Pointer for Sending and Verifying Payments
This tutorial will guide you through the process of sending and verifying payments using Chimoney's API and Payment Pointers. We will cover setting up your environment, sending a payment to an Interledger Wallet Address, and verifying the transaction.
## 1. Environment Setup
Before you start, you'll need a Chimoney developer account and your API key.
### Getting Your API Key
1. Go to the Chimoney Developer Portal and create an account.
2. Log in and navigate to the "Developers" tab to create a new App.
3. Your API Key will be generated. Copy it and keep it safe.
**Note**: This tutorial covers all steps in sandbox mode. The sandbox base URL is https://api-v2-sandbox.chimoney.io/v0.2.4/ For those working on production, please replace the sandbox base URL with the production URL: https://api.chimoney.io/v0.2.4/
### Setting up your .env file
Create a `.env` file in your project's root directory to store your API key securely.
```
CHIMONEY_API_KEY="YOUR_API_KEY"
```
### Dependencies
This tutorial uses Node.js and the node-fetch library to make API requests. Make sure you have Node.js installed and then install node-fetch:
```bash
npm install node-fetch
```
## 2. Step-by-Step Guide On P2P Transfers
### Step 1: Send a Payment
To send a payment to an Interledger Wallet Address, you will use the `POST /v0.2.4/payouts/interledger-wallet-address` endpoint.
**EndPoint**:https://api.chimoney.io/v0.2.4/payouts/interledger-wallet-address
#### Explanation
This endpoint allows you to initiate a payout to a user's Interledger Payment Pointer. You need to specify the debit currency and provide a list of wallets to send to — including the recipient's Interledger Wallet Address, the currency, the amount, and a narration for the transaction.
#### Code Snippet (JavaScript)
```javascript
import fetch from 'node-fetch';
const sendPayment = async () => {
const url = 'https://api-v2-sandbox.chimoney.io/v0.2.4/payouts/interledger-wallet-address';
const options = {
method: 'POST',
headers: {
'accept': 'application/json',
'content-type': 'application/json',
'X-API-KEY': process.env.CHIMONEY_API_KEY
},
body: JSON.stringify({
debitCurrency: 'USD',
interledgerWallets: [
{
interledgerWalletAddress: '$ilp.uphold.com/24NNrh1B32g4', // Example payment pointer
currency: 'USD',
amountToDeliver: 1,
narration: 'Payment for services'
}
]
})
};
try {
const res = await fetch(url, options);
const json = await res.json();
console.log(json);
} catch (err) {
console.error('error:' + err);
}
};
sendPayment();
```
### Step 2: Verify the Payment
After sending a payment, you will receive an `issueID`. You can use this ID to verify the status of your transaction with the `POST /v0.2.4/payment/verify` endpoint.
**EndPoint**:https://api.chimoney.io/v0.2.4/payment/verify
#### Explanation
This endpoint helps you confirm if a transaction was successful. You pass the issueID from the previous step in the request body. This endpoint is particularly useful for verifying the final status of the transaction, as it will confirm one of these four states: "failed", "expired", "fraud", or "paid".
#### Code Snippet (JavaScript)
```javascript
import fetch from 'node-fetch';
const verifyPayment = async (issueID) => {
const url = 'https://api-v2-sandbox.chimoney.io/v0.2.4/payment/verify';
const options = {
method: 'POST',
headers: {
'accept': 'application/json',
'content-type': 'application/json',
'X-API-KEY': process.env.CHIMONEY_API_KEY
},
body: JSON.stringify({
id: issueID
})
};
try {
const res = await fetch(url, options);
const json = await res.json();
console.log(json);
} catch (err) {
console.error('error:' + err);
}
};
// Replace with the issueID from your "Send Payment" response
const issueID = "YOUR_ISSUE_ID";
verifyPayment(issueID);
```
## 3. Optional Features
### Sending Payments in Multiple Currencies
Chimoney's API supports multiple currencies. To send a payment in a different currency, change the `debitCurrency` and the `currency` in the `interledgerWallets` array to your desired currency code (e.g., "CAD", "NGN").
### Transaction Notifications
For transaction notifications, you can set up a webhook in your Chimoney developer dashboard. This allows Chimoney to send real-time updates about your transactions to a URL you specify.
## 4. Conclusion and Further Resources
You have now learned the basic workflow for sending and verifying payments with Chimoney's Payment Pointer integration.
For more detailed information, refer to the official documentation:
- **Payment Pointer Integration Use Case Guide:**
https://chimoney.io/usecases/interledger-receive-and-send-payments/
- **Chimoney API Reference:**
https://chimoney.readme.io/reference/getting-started-with-your-api
- **Introductory Video:**
For a great introduction to the Chimoney API, check out this Payment API 101 video.
https://www.youtube.com/watch?v=VItvZbPH9cU
================================================
FILE: submissions/Chimoney-Python/LICENSE
================================================
MIT License
Copyright (c) 2022 Asikhalaye Samuel
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
================================================
FILE: submissions/Chimoney-Python/README.md
================================================
# PyChimoney
pychimoney is a python wrapper for Chimoney
- Account
- Info
- Payout
- Mobile Money
- Wallet
- Sub-Account
- Redeem
## Getting Started
- Register with Chimoney
- Request for API KEY from support
- set Your "CHIMONEY_AUTH_KEY" environment variable
## Installing
- pip install chimoney-py
### OR
- git clone "the repo"
- cd pychimoney
- python setup.py install or
- pip3 install .
## Usage
#### Importing the package
```python
from chimoney import Chimoney
```
#### Creating an instance of the Chimoney class
```python
chimoney = Chimoney.set_api_key("API-KEY")
```
#### Full Example
```python
from pychimoney import Chimoney
import os
# Initialize Chimoney
chimoney = Chimoney.set_api_key("CHIMONEY_AUTH_KEY")
```
#### Using the Account API
```python
chimoney.account.required_function(params)
```
## TODO
- [x] Add all Endpoints
- [ ] Write Unit Tests
- [x] Package the Library
- [x] Add to Pip
- [ ] Add Pytest and Covrage for Test
- [ ] Documentation
================================================
FILE: submissions/Chimoney-Python/build/lib/pychimoney/__init__.py
================================================
from .Base import BaseAPI
from .Info import Info
from .Account import Account
from .Payouts import Payouts
from .SubAccount import SubAccount
from .Wallet import Wallet
from .Redeem import Redeem
from .Chimoney import Chimoney
from .Payments import Payments
from .AI import AI
================================================
FILE: submissions/Chimoney-Python/chimoney/AI.py
================================================
from chimoney import BaseAPI
class AI(BaseAPI):
"""
A class that extends the BaseAPI class to handle AI-based invoice generation requests.
Methods:
--------
invoice_gen(instruction: str) -> dict
Generates an invoice based on a given instruction.
"""
def invoice_gen(self, instruction: str):
"""
Generates an invoice by sending a POST request with the given instruction to the AI endpoint.
Parameters:
-----------
instruction : str
A description or set of details required to generate the invoice. It should specify key elements
like items, quantities, prices, and any additional instructions for the invoice layout.
Returns:
--------
dict
A dictionary containing the response from the invoice generation API, which includes details of the generated invoice.
Raises:
-------
ValueError
If the 'instruction' parameter is empty or None.
"""
if not instruction:
raise ValueError("Instruction is required")
payload = {
"instruction": instruction
}
return self._handle_request("POST", "/v0.2/ai/invoice/generate", payload)
================================================
FILE: submissions/Chimoney-Python/chimoney/Account.py
================================================
from chimoney import BaseAPI
class Account(BaseAPI):
"""
Account Endpoints Wrapper
This class wraps the Account endpoints of the Chi Money API.
list of endpoints:
- transactions_by_issue_id
- all_transaction
- transaction_by_id
- account_transfer
- delete_unpaid_transaction
"""
def transactions_by_issue_id(self, issue_id, sub_account=None) -> dict:
"""
This function returns a list of transactions by issue ID.
Args:
issue_id (str): The issue ID of the transaction.(required)
sub_account (str): The sub account of the transaction.
Returns:
The JSON response fron the Chimoney API
"""
if not isinstance(issue_id, str):
raise TypeError("Issue ID must be a string.")
if not issue_id:
raise ValueError("Issue ID is required.")
params = {"issueID": issue_id}
payload = {}
if sub_account:
payload["subAccount"] = sub_account
return self._handle_request(
"POST", "/v0.2/accounts/issue-id-transactions", params=params, data=payload
)
def all_transaction(self, sub_account=None) -> dict:
"""
This function returns a list of transactions by account .
Args:
sub_account(str): The sub account of the transaction.
Returns:
The JSON response from the Chimoney API
"""
payload = {}
if sub_account:
payload["subAccount"] = sub_account
return self._handle_request(
"POST",
"/v0.2/accounts/transactions",
data=payload,
)
def transaction_by_id(self, transaction_id, sub_account=None) -> dict:
"""
This function returns a transaction by ID.
Args:
transaction_id(str): The ID of the transaction.(required)
sub_account(str): The sub account of the transaction.
Returns:
The JSON response from the Chimoney API
"""
if not isinstance(transaction_id, str):
raise TypeError("Transaction ID must be a string.")
if not transaction_id:
raise ValueError("Transaction ID is required.")
params = {"id": transaction_id}
payload = {}
if sub_account:
payload["subAccount"] = sub_account
return self._handle_request(
"GET", "/v0.2/accounts/transaction", params=params, data=payload
)
def account_transfer(self, receiver, amount, wallet, sub_account=None) -> dict:
"""
This function transfers funds from one account to another.
Args:
reciever(str): The receiver of the funds.
amount(float): The amount of the funds in USD.
wallet(str): The wallet type.[chi, momo, airtime]
sub_aacount(str): The sub account of the transaction.
Returns:
The JSON response from Chimoney API
"""
if not isinstance(receiver, str):
raise TypeError("Receiver must be a string.")
if not isinstance(amount, int):
raise TypeError("Amount must be an integer.")
if not isinstance(wallet, str):
raise TypeError("Wallet must be a string.")
if not receiver and amount and wallet:
raise ValueError("Reciver, amount and wallet are required.")
payload = {
"receiver": receiver,
"valueInUSD": amount,
"wallet": wallet,
}
if sub_account:
payload["subAccount"] = sub_account
return self._handle_request(
"POST",
"/v0.2/accounts/transfer",
data=payload,
)
def delete_unpaid_transaction(self, transaction_id, sub_account=None):
"""
This function deletes an unpaid transaction.
Args:
transaction_id(str): The ID of the transaction.(required)
sub_account(str): The sub account of the transaction
Returns:
The JSON response from the Chimoney API
"""
if not isinstance(transaction_id, str):
raise TypeError("Transaction ID must be a string.")
if not transaction_id:
raise ValueError("Transaction ID is required.")
params = {"chiRef": transaction_id}
if sub_account:
params["subAccount"] = sub_account
return self._handle_request(
"DELETE", "/v0.2/accounts/delete-unpaid-transaction", params=params
)
================================================
FILE: submissions/Chimoney-Python/chimoney/Base.py
================================================
import json
import os
import logging
import time
import requests
from requests.exceptions import ConnectTimeout, HTTPError
from requests.adapters import HTTPAdapter
from urllib3 import Retry
from chimoney.Errors import MissingAuthKeyError
logging.basicConfig(level=logging.INFO)
class APIResponse:
"""
A class to represent the response from the API.
This class is used to encapsulate the data returned from the API request,
along with its status code, success status, and any potential error messages.
Attributes:
data (dict or None): The data returned from the API, typically in JSON format.
status_code (int): The HTTP status code of the API response.
success (bool): A flag indicating whether the API request was successful (default is True).
error (str or None): An optional error message, populated if the request failed.
Args:
data (dict or None): The data returned from the API.
status_code (int): The HTTP status code of the response.
success (bool): A flag indicating whether the request was successful (default is True).
error (str or None): An error message if the request failed (default is None).
"""
def __init__(self, data, status_code, success=True, error=None):
self.data = data
self.status_code = status_code
self.success = success
self.error = error
class BaseAPI(object):
"""
This class handles the requests to the API.
"""
_PRODUCTION_BASE_URL = "https://api.chimoney.io"
_SANDBOX_BASE_URL = "https://api-v2-sandbox.chimoney.io"
_CONTENT_TYPE = "application/json"
_ACCEPT = "application/json"
def __init__(self):
"""
Initialize the BaseAPI object.
Args:
sandbox (bool): Set to True to use the sandbox environment.
"""
self._sandbox = os.getenv("CHIMONEY_SANDBOX", "").lower() == "true"
self.base_url = (
self._SANDBOX_BASE_URL if self._sandbox else self._PRODUCTION_BASE_URL
)
self._chimoney_auth_key = os.getenv("CHIMONEY_AUTH_KEY")
if self._chimoney_auth_key is None:
raise MissingAuthKeyError("Missing CHIMONEY_AUTH_KEY environment variable.")
self._default_timeout = 10
self.session = requests.Session()
self.retries = Retry(total=3, backoff_factor=0.3, status_forcelist=[500, 502, 503, 504])
self.session.mount("https://", HTTPAdapter(max_retries=self.retries))
def headers(self):
"""
This function returns the headers for the API request.
Return:
The headers for the API request.
"""
return {
"Content-Type": self._CONTENT_TYPE,
"Accept": self._ACCEPT,
"X-API-KEY": self._chimoney_auth_key,
}
def parse_json(self, response):
"""
This function parses the JSON response from the API.
Args:
respnse(str): The response from the API.
Returns:
The parsed JSON response.
"""
data = response.json()
return data, response.status_code
def _url(self, path):
"""
This function returns the URL for the API request.
Args:
path(str): The path for the API request.
Returns:
The URL for the API request.
"""
return self.base_url + path
def _handle_request(
self, method_type, path, data=None, params=None, timeout=None, retry_count=0):
"""
Handle requests to the API.
Args:
method_type (str): The type of request to make.
path (str): The path to the API endpoint.
data (dict): The data to send to the API.
params (dict): The parameters to send to the API.
Returns:
dict: The response from the Chi Money API.
"""
max_retries = 3
logging.info("Request: %s %s | Data: %s | Params: %s",
method_type, self._url(path), data, params)
payload = json.dumps(data) if data else None
timeout = timeout or self._default_timeout
try:
response = self.session.request(
method=method_type,
url=self._url(path),
headers=self.headers(),
data=payload,
params=params,
timeout=timeout
)
response.raise_for_status()
if response.status_code == 429:
# retry_after = int(response.headers.get('Retry-After', 60))
# logging.warning("Rate limit exceeded. Retrying after %d seconds.", retry_after)
# time.sleep(retry_after)
# return self._handle_request(method_type, path, data, params, timeout)
retry_after = int(response.headers.get('Retry-After', 60))
logging.warning("Rate limit exceeded. Retrying after %d seconds.", retry_after)
if retry_count < max_retries:
time.sleep(retry_after)
return self._handle_request(
method_type, path, data, params, timeout, retry_count + 1)
else:
return APIResponse(
data=None, status_code=429, success=False, error="Max retries exceeded.")
logging.info("Response: %d | %s", response.status_code, response.json())
return APIResponse(data=response.json(), status_code=response.status_code)
except HTTPError as http_err:
logging.error("HTTP error occurred: %s", http_err)
return APIResponse(data=None,
status_code=response.status_code, success=False, error=str(http_err))
except (ConnectTimeout, ConnectionError) as exc:
logging.error("Connection error occurred: %s", exc)
return APIResponse(data=None,
status_code=None, success=False, error=str(exc))
================================================
FILE: submissions/Chimoney-Python/chimoney/Chimoney.py
================================================
"""
Chimoney API Integration
This module provides a Python wrapper for the Chi Money API, enabling access to
various functionalities such as retrieving account information, handling payouts,
managing wallets, and redeeming rewards. The module also includes support for both
production and sandbox environments, making it suitable for testing and live deployments.
Classes:
Chimoney: This is the root API class that provides access to different services
(Info, Account, Payouts, SubAccount, Wallet, Redeem) of the Chimoney API.
Functions:
set_api_key(cls, auth_key):
A class method of Chimoney that sets the API key needed for authentication
with the Chi Money API.
Modules used:
os: Used for managing environment variables to set the API key and enable sandbox mode.
chimoney.Info, chimoney.Account, chimoney.Payouts, chimoney.SubAccount,
chimoney.Wallet, chimoney.Redeem:
These are specific modules that interact with the corresponding endpoints
of the Chi Money API.
Environment Variables:
CHIMONEY_AUTH_KEY: The API key required to authenticate requests to the Chi Money API.
CHIMONEY_SANDBOX: An optional variable that, when set to "True", directs the
API requests to the sandbox environment.
Example usage:
# Initialize the Chimoney API in production mode
chi_api = Chimoney()
# Set the API key
Chimoney.set_api_key('your_api_key')
# Initialize the Chimoney API in sandbox mode
chi_api_sandbox = Chimoney(sandbox=True)
"""
import os
from chimoney import Info, Account, Payments, Payouts, SubAccount, Wallet, Redeem, AI
class Chimoney:
"""
The root API class for interacting with the Chi Money API.
This class serves as the entry point to access various API functionalities such as
retrieving information, managing accounts, processing payouts, handling subaccounts,
managing wallets, and redeeming rewards.It initializes and exposes instances of the
respective API modules (Info, Account, Payouts, SubAccount, Wallet, Redeem).
Attributes:
info (Info): Provides access to information-related API operations.
account (Account): Manages account-related operations.
payouts (Payouts): Handles payout-related operations.
subaccount (SubAccount): Manages subaccount-related operations.
wallet (Wallet): Manages wallet operations.
redeem (Redeem): Manages reward redemption-related operations.
Args:
sandbox (bool): Determines whether to use the sandbox environment.
If True, it sets the CHIMONEY_SANDBOX
environment variable to True, directing API requests
to the sandbox environment. The default is False.
Methods:
set_api_key(cls, auth_key):
Class method that sets the API key for authenticating requests to the Chi Money API.
Args:
auth_key (str): The API key for authenticating requests.
Returns:
Chimoney: An instance of the Chimoney class with the specified API key.
"""
def __init__(self, sandbox=False):
self.info = Info()
self.account = Account()
self.payouts = Payouts()
self.subaccount = SubAccount()
self.wallet = Wallet()
self.redeem = Redeem()
self.payment = Payments()
self.ai = AI()
if sandbox:
os.environ["CHIMONEY_SANDBOX"] = "True"
@classmethod
def set_api_key(cls, auth_key):
"""
This function sets the API key for the Chi Money API.
Args:
auth_key(str): The API key for the Chi Money API.
Return:
The Chi Money API object.
"""
os.environ["CHIMONEY_AUTH_KEY"] = auth_key
# return an instance of the Chimoney class
return Chimoney()
# def ping(self):
# """
# Ping the API to check if it is up and running.
# :return: The response from the Chi Money API.
# :rtype: dict
# """
# return self._handle_request("GET", "")
================================================
FILE: submissions/Chimoney-Python/chimoney/Errors.py
================================================
class PyChimoneyError(Exception):
"""Base class for PyChimoney errors."""
pass
class MissingAuthKeyError(PyChimoneyError):
"""Raised when the user has not authenticated."""
pass
class InvalidMethodError(PyChimoneyError):
"""Raised when the method is not valid."""
pass
class Error(PyChimoneyError):
"""Random exception taker"""
pass
================================================
FILE: submissions/Chimoney-Python/chimoney/Info.py
================================================
from chimoney import BaseAPI
class Info(BaseAPI):
"""
This class handles the Info API
"""
def airtime_countries(self) -> dict:
"""
This function returns a list of countries that supports airtime.
Returns:
dict: The response from the Chimoney API.
"""
return self._handle_request("GET", "/v0.2/info/airtime-countries")
def assets(self, country_code=None) -> dict:
"""
This function returns a list of supported assets.
Args:
country_code(str, optional): Country Code Symbol e.g. NG, GH
Return:
dict: The response from the Chimoney API.
"""
params = {}
if country_code is not None:
params["countryCode"] = country_code
return self._handle_request("GET", "/v0.2/info/assets", params=params)
def banks(self, country="NG") -> dict:
"""
This function returns a list of supported banks and banks code.
Args:
country(str): The country Code.
Default Country is Nigeria(NG).
Return:
dict: The response from the Chi Money API.
"""
if not isinstance(country, str):
raise TypeError("Country must be a string.")
if not country:
raise ValueError("Country is required.")
return self._handle_request(
"GET", "/v0.2/info/country-banks", params={"countryCode": country}
)
def local_ammount_in_usd(self, source_currency, ammount_in_local):
"""
This function returns the equivalent of local currency in USD.
Args:
source_currency(str): The source currency.
ammount_in_local(int): The ammount in local currency.
Returns:
dict: The response from the Chi Money API.
"""
if not isinstance(ammount_in_local, float):
raise TypeError("Ammount must be an integer.")
if not isinstance(source_currency, str):
raise TypeError("Source currency must be a string.")
if not source_currency and ammount_in_local:
raise ValueError("Source currency and ammount are required.")
return self._handle_request(
"GET",
"/v0.2/info/local-amount-in-usd",
params={
"originCurrency": source_currency,
"amountInOriginCurrency": ammount_in_local,
},
)
def mobile_money_codes(self):
"""
This function returns a list of supported mobile money codes.
"""
return self._handle_request("GET", "/v0.2/info/mobile-money-codes")
def usd_to_local(self, destination_currency, ammount_in_usd):
"""
This function returns the equivalent of USD in the destination
currency.
Args:
destination_currency(str): The destination currency e.g. NGN, KES
ammount_in_usd(int): The ammount in USD.
Return:
dict: The response from the Chi Money API.
"""
if not isinstance(ammount_in_usd, int):
raise TypeError("Ammount must be an integer.")
if not isinstance(destination_currency, str):
raise TypeError("Destination currency must be a string.")
if not destination_currency and ammount_in_usd:
raise ValueError("Destination currency and ammount are required.")
return self._handle_request(
"GET",
"/v0.2/info/usd-amount-in-local",
params={
"destinationCurrency": destination_currency,
"amountInUSD": ammount_in_usd,
},
)
def get_exchange_rates(self) -> dict:
"""
This function returns all the exchanges rates
Returns:
dict: The respnse from the Chimoney API
"""
return self._handle_request("GET", "/v0.2/info/exchange-rates")
def get_bank_branches(self, bank_code: str) -> dict:
"""
This function gets a list of branches for a specific bank.
Args:
bank_code (str): The code identifying the bank.
Returns:
dict: The response from the Chimoney API
"""
params = {}
if bank_code:
params["bankCode"] = bank_code
if not bank_code:
raise ValueError("Bank Code is required.")
return self._handle_request("GET", "/v0.2/info/bank-branches", params=params)
def verify_bank_account_number(self, account_number: list) -> dict:
"""
This function verifies bank account numbers.
Args:
account_number (list): A list of bank account numbers to be verified.
Returns:
dict: The response from the Chimoney API
"""
if not account_number:
raise ValueError("Account Details are required.")
params = {}
if account_number:
params["verifyAccountNumbers"] = account_number
return self._handle_request(
"POST", "/v0.2/info/verify-bank-account-number", params=params
)
================================================
FILE: submissions/Chimoney-Python/chimoney/Payments.py
================================================
# from Base import APIResponse
from chimoney import BaseAPI
class Payments(BaseAPI):
"""
Chimoney's Payment Wrapper
"""
def initiate_payment(
self,
value_in_usd,
payer_email,
currency,
amount,
redirect_url,
wallet_id,
narration,
sub_account,
meta: dict,
turn_off_notification: bool
) -> dict:
"""
This endpoint allows you to request for funds from another party
by initiating a payment request via Chimoney.
"""
payload = {
"value_in_usd": value_in_usd,
"payer_email": payer_email,
"currency": currency,
"amount": amount,
"redirectURL": redirect_url,
"WalletID": wallet_id,
"narration": narration,
"subAccount": sub_account,
"meta": meta,
"turnOffNotification": turn_off_notification
}
return self._handle_request("POST", "/v0.2/payment/initiate", payload)
def verify_payment(self, sub_account, payment_id):
payload = {}
if not payment_id:
raise ValueError("id is required")
payload = {"id": payment_id}
if sub_account:
payload["subAccount"] = sub_account
return self._handle_request("POST", "/v0.2/payment/verify", payload)
def simulate_transaction(self, issue_id, status, sub_account):
if not issue_id and status:
raise ValueError("IssueID and Status are required")
payload = {
"issueID": issue_id,
"status": status,
"subAccount": sub_account
}
return self._handle_request("POST", "/v0.2/payment/simulate", payload)
================================================
FILE: submissions/Chimoney-Python/chimoney/Payouts.py
================================================
from chimoney import BaseAPI
class Payouts(BaseAPI):
"""
This Wraps the Payouts API of Chi Money
"""
def airtime(self, airtimes, subaccount=None, turn_off_notification=None):
"""
This function handles the airtime API.
Args:
airtimes(list, required): A list of dictionaries containing the airtime details.
subaccount(str): The subaccount to use.
turn_off_notificaiton(bool): None by default
example:
airtime = [
{
countryToSend: "Nigeria",
phoneNumber: "+2348123456789",
valueInUSD: 123
}
]
Return:
The JSON response from the Chi Money API.
"""
if not isinstance(airtimes, list):
raise ValueError("airtimes must be a list of dictionaries")
payload = {"airtimes": airtimes}
if subaccount:
payload["subAccount"] = subaccount
if turn_off_notification is not None:
payload["turnOffNotification"] = turn_off_notification
return self._handle_request("POST", "/v0.2/payouts/airtime", data=payload)
def bank(self, banks, subaccount=None, turn_off_notification=None):
"""
This function handles the bank API.
Args:
banks(list, required): A list of dictionaries containing the bank details.
subaccount(str): The subaccount to use.
turn_off_notificaiton(bool): None by default
example:
banks = [
{
"countryToSend": "Nigeria",
"account_bank": "044",
"account_number": "0690000031",
"valueInUSD": 1,
"reference": "1234567890",
"fullname": "James John",
"branch_code": "GH190101"
}
]
Returns:
The JSON response from the Chi Money API.
"""
if not isinstance(banks, list):
raise ValueError("banks must be a list of dictionaries")
payload = {"banks": banks}
if subaccount:
payload["subAccount"] = subaccount
if turn_off_notification is not None:
payload["turnOffNotification"] = turn_off_notification
return self._handle_request("POST", "/v0.2/payouts/bank", data=payload)
def chimoney(self, chimoneys, subaccount=None, turn_off_notification=None):
"""
This function handles the chimoney API.
Args:
chimoneys(list, required): A list of dictionaries containing the chimoney details.
subaccount(str): The subaccount to use.
turn_off_notification(bool): None by Default
example:
chimoneys = [
{
"valueInUSD": 1,
"email": "test@example.com",
"phone": "+2341234567890",
}
]
Return:
The response from the Chi Money API.
"""
if not isinstance(chimoneys, list):
raise ValueError("chimoney must be a list of dictionaries")
payload = {"chimoneys": chimoneys}
if subaccount:
payload["subAccount"] = subaccount
if turn_off_notification is not None:
payload["turnOffNotification"] = turn_off_notification
return self._handle_request("POST", "/v0.2/payouts/chimoney", data=payload)
def mobile_money(self, momos, subaccount=None, turn_off_notification=None):
"""
This function handles the mobile money API.
Args:
momos(list): A list of dictionaries containing the mobile money details.
subaccount(str): The subaccount to be used.
turn_off_notification(bool): None by Default
example:
momos = [
{
"countryToSend": "Nigeria",
"phoneNumber": "+2348123456789",
"valueInUSD": 1,
"reference": "1234567890",
"momoCode": "MPS"
}
]
Return:
The JSON response from the Chi Money API.
"""
if not isinstance(momos, list):
raise ValueError("mobile_money must be a list of dictionaries")
payload = {"momos": momos}
if subaccount:
payload["subAccount"] = subaccount
if turn_off_notification is not None:
payload["turnOffNotification"] = turn_off_notification
return self._handle_request("POST", "/v0.2/payouts/mobile-money", data=payload)
def gift_card(self, gift_cards, subaccount=None, turn_off_notification=None):
"""
This function handles the gift card API.
Args:
gift_cards(list): A list of dictionaries containing the gift card details.
subaccount(str): The subaccount to use.
turn_off_notification(bool): None by Default.
example:
gift_cards = [
{
"email": "test@example.com",
"valueInUSD": 1,
"redeemData": {
"productId": 5,
"countryCode": "NG"
"valueInLocalCurrency": 1000
}
}
]
Return:
The JSON response from the Chi Money API.
"""
if not isinstance(gift_cards, list):
raise ValueError("gift_cards must be a list of dictionaries")
payload = {"giftcards": gift_cards}
if subaccount:
payload["subAccount"] = subaccount
if turn_off_notification is not None:
payload["turnOffNotification"] = turn_off_notification
return self._handle_request("POST", "/v0.2/payouts/gift-card", data=payload)
def status(self, chi_ref, subaccount=None):
"""
This function handles the status API.
Args:
chi_ref(str): The Chi Money reference.
subaccount(str): The subaccount to use.
Return:
dict: The response from the Chimoney API.
"""
if not chi_ref:
raise ValueError("chi_ref is required")
payload = {"chiRef": chi_ref}
if subaccount:
payload["subAccount"] = subaccount
return self._handle_request("POST", "/v0.2/payouts/status", data=payload)
def initiate_chimoney(
self,
chimoneys,
crypto_payments=None,
subaccount=None,
turn_off_notification=None,
redirect_url=None,
enable_xumm_payment=None,
enable_interledger_payment=None,
):
"""
This function handles the initiate chimoney API.
example:
chimoneys = [
{
"email": "test@example",
"phone": "+16471112222",
"valueInUSD": 1,
"twitter": "@test"
}
]
crypto_payments = [
{
"xrpl": {
"address": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
"issuer": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
"currency": "XRP"
}
}
]
Args:
chimoneys(list, required): A list of dictionaries containing the chimoney details.
crypto_payments(list): A list of dictionaries containing the crypto payment details.
subaccount(str): The subaccount to be used.
turn_off_notification(bool): None by Default.
redirect_url(str): The URL to redirect to after payment is confirmed.
enable_xumm_payment(bool): To generate a XUMM transaction sign link.
enable_interledger_payment(bool): To generate an Open Payment
payment request to pay with Interledger.
Return:
dict: The response from the Chi Money API.
"""
if not isinstance(chimoneys, list):
raise ValueError("chimoneys must be a list of dictionaries")
if not isinstance(crypto_payments, list):
raise ValueError("crypto_payments must be a list of dictionaries")
payload = {"chimoneys": chimoneys, "cryptoPayment": crypto_payments}
if subaccount:
payload["subAccount"] = subaccount
if turn_off_notification is not None:
payload["turnOffNotification"] = turn_off_notification
if redirect_url:
payload["redirect_url"] = redirect_url
if enable_xumm_payment:
payload["enableXUMMPayment"] = enable_xumm_payment
if enable_interledger_payment:
payload["enableInterledgerPayment"] = enable_interledger_payment
return self._handle_request(
"POST", "/v0.2/payouts/initiate-chimoney", data=payload
)
def wallet(self, subaccount=None, turn_off_notifications=None, wallets=None):
"""
The function handles the payout to Chimoney Wallet
Args:
subaccount(str): The subaccount to be used.
turn_off_notification(bool): None by default
wallets(list, required): A list of dictionaries containing wallet details
Returns:
dict: The response from Chimoney API
"""
if not isinstance(wallets, list):
return ValueError("wallets must be a list of dictionaries")
payload = {"wallets": wallets}
if subaccount:
payload["subAccount"] = subaccount
if turn_off_notifications is not None:
payload["turnOffNotifications"] = turn_off_notifications
return self._handle_request("POST", "/v0.2/payouts/wallet", data=payload)
================================================
FILE: submissions/Chimoney-Python/chimoney/Redeem.py
================================================
from chimoney import BaseAPI
class Redeem(BaseAPI):
"""
This is a Wrapper for the Redeem API of Chimoney
"""
def airtime(
self, chi_ref, phone_number, country_to_send, test=False, sub_account=None
):
"""
This function handles the airtime API.
Args:
chi_ref(str): The Chimoney reference for the transaction.
phone_number(str): The phone number to send the airtime to.
country_to_send(str): The country to send the airtime to.
test(bool): A boolean to indicate if the transaction is a test.
sub_account(str): The subaccount to be used.
Return:
The JSON response from the Chimoney API.
"""
payload = {
"chiRef": chi_ref,
"phoneNumber": phone_number,
"countryToSend": country_to_send,
"meta": {"test": test},
}
if sub_account:
payload["subAccount"] = sub_account
return self._handle_request("POST", "/v0.2/redeem/airtime", payload)
def any(
self,
chi_ref,
redeem_data: list,
test=False,
sub_account=None,
):
"""
This function handles the any API.
Args:
chi_ref(str): The Chi Money reference for the transaction.
redeem_data(list): A list of dictionaries containing the redeem details.
test(bool): A boolean to indicate if the transaction is a test.
sub_account(str): The subaccount to be used.
example:
redeem_data = [
{
"countryCode": "NG",
"productId": 1,
"valueInLocalCurrency": 1000,
}
]
Return:
The JSON response from the Chimoney API.
"""
payload = {
"chiRef": chi_ref,
"redeemData": redeem_data,
"meta": {"test": test},
}
if sub_account:
payload["subAccount"] = sub_account
return self._handle_request("POST", "/v0.2/redeem/any", payload)
def chimoney(self, chimoneys, sub_account=None):
"""
This function handles the initiate chimoney API.
Args:
chimoneys(dict): A list of dictionaries containing the redeem details.
sub_account(str): The subaccount to use.
example:
chimoneys = {
{
"object": "chimoney",
}
}
Return:
The JSON response from the Chi Money API.
"""
if not chimoneys:
raise ValueError("chimoneys must be a list of dictionaries")
payload = {"chimoneys": chimoneys}
if sub_account:
payload["subAccount"] = sub_account
return self._handle_request("POST", "/v0.2/redeem/chimoney", payload)
def giftcard(self, chi_ref, redeem_options, sub_account=None):
"""
This function handles the giftcard API.
Args:
chi_ref(str): The Chi Money reference for the transaction.
redeem_options(dict): A list of dictionaries containing the redeem details.
sub_account(str): The subaccount to be used.
example:
redeem_options = {
{
"object": "giftcard",
}
}
Return:
The JSON response from the Chimoney API.
"""
payload = {"chiRef": chi_ref, "redeemOptions": redeem_options}
if sub_account:
payload["subAccount"] = sub_account
return self._handle_request("/v0.2/redeem/gift-card", payload)
def mobile_money(self, chi_ref, redeem_options, sub_account=None):
"""
This function handles the mobile money API.
Args:
chi_ref(str): The Chi Money reference for the transaction.
redeem_options(dict): A list of dictionaries containing the redeem details.
sub_account(str): The subaccount to use.
example:
redeem_options = {
{
"object": "mobile_money",
}
}
Return:
The JSON response from the Chi Money API.
"""
payload = {"chiRef": chi_ref, "redeemOptions": redeem_options}
if sub_account:
payload["subAccount"] = sub_account
return self._handle_request("POST", "/v0.2/redeem/mobile-money", payload)
================================================
FILE: submissions/Chimoney-Python/chimoney/SubAccount.py
================================================
from chimoney import BaseAPI
class SubAccount(BaseAPI):
"""
This is a Wrapper for the SubAccount API of Chimoney
"""
def create(self, email, name):
"""
The function creates the user for the subaccount
Args:
email(str): The email of the user
name(str): The name of the user
Return:
The JSON response from the Chimoney API
"""
if not email:
raise ValueError("email is required")
if not name:
raise ValueError("name is required")
payload = {"email": email, "name": name}
return self._handle_request("POST", "/v0.2/subaccount", payload)
def delete(self, user_id):
"""
The function deletes the user via it's id
Args:
user_id(str): The user's id
Return:
The JSON response from the Chimoney API
"""
if not id:
raise ValueError("id is required")
payload = {"id": user_id}
return self._handle_request("DELETE", "/v0.2/subaccount", payload)
def get_detials(self, user_id):
"""
The function gets the user details
Args:
user_id(str): The user's id
Return:
The JSON response from the Chimoney API
"""
if not id:
raise ValueError("id is required")
payload = {"id": user_id}
return self._handle_request("GET", "/v0.2/subaccount", payload)
def list(self):
"""
This function lists out all the subaccounts
"""
return self._handle_request("GET", "/v0.2/subaccount/list")
================================================
FILE: submissions/Chimoney-Python/chimoney/Wallet.py
================================================
from chimoney import BaseAPI
class Wallet(BaseAPI):
"""
This class handles the Wallet API of Chimoney
"""
def list(self, subaccount=None):
"""
This functions returns all associated wallets
Args:
subaccount(str): The subaccount to be used.
Return:
JSON response from Chimoney API
"""
payload = {}
if subaccount:
payload["subaccount"] = subaccount
return self._handle_request("POST", "/v0.2/wallet", payload)
def detials(self, wallet_id, subaccount=None):
"""
The function returns single wallet details
Args:
wallet_id(str): The wallet id(required)
subaccount(str): The subaccount to be used
Returns:
JSON response form the Chimoney API
"""
if not id:
raise ValueError("id is required")
payload = {"id": wallet_id}
if subaccount:
payload["subaccount"] = subaccount
return self._handle_request("POST", "/v0.2/wallet", payload)
def transfer(self, receiver_id, wallet_type, amount, subaccount=None):
"""
This function handles transfers between wallets
Args:
reciever_id(str): Valid Chimoney User or Organization ID.(required)
wallet_type: Wallet type[chi, momo, airtime]
amount(str): Amount in USD(required)
subaccount(str): The subaccount to be used
Returns:
JSON response from Chimoney API
"""
if not receiver_id:
raise ValueError("reciver_id is required")
if not wallet_type:
raise ValueError("wallet_type is required")
if not amount:
raise ValueError("amount is required")
payload = {
"reciver_id": receiver_id,
"wallet_type": wallet_type,
"amount": amount,
}
if subaccount:
payload["subaccount"] = subaccount
return self._handle_request("POST", "/v0.2/wallets/transfer", payload)
================================================
FILE: submissions/Chimoney-Python/chimoney/__init__.py
================================================
from .Base import BaseAPI
from .Info import Info
from .Account import Account
from .Payouts import Payouts
from .SubAccount import SubAccount
from .Wallet import Wallet
from .Redeem import Redeem
from .Chimoney import Chimoney
from .Payments import Payments
from .AI import AI
================================================
FILE: submissions/Chimoney-Python/examples/chimoney_examples.py
================================================
import os
from chimoney import Chimoney
os.environ["CHIMONEY_AUTH_KEY"] = "API_KEY"
chimoney = Chimoney()
def test():
(data, status) = chimoney.ping()
return data
def avaliable_countries():
return chimoney.airtime_countries()
if __name__ == "__main__":
print(test())
print(avaliable_countries())
================================================
FILE: submissions/Chimoney-Python/examples/test.py
================================================
import os
from chimoney import Chimoney
chimoney = Chimoney.set_api_key("API_KEY")
chimoneys = [
{
"email": "test@email.com",
"valueInUSD": 1,
"twitter": "@thelimeskies"
}
]
if __name__ == "__main__":
# print(chimoney.ping()) # TODO: Add ping function to pychimoney
print(chimoney.payouts.initiate_chimoney(chimoneys=chimoneys))
================================================
FILE: submissions/Chimoney-Python/setup.py
================================================
from setuptools import setup, find_packages
with open("README.md", "r") as fh:
long_description = fh.read()
setup(
name="chimoney-py",
version="0.0.2",
author="Asikhalaye Samuel",
author_email="samuelasikhalaye@gmail.com",
description="A Python package for Chimoney",
long_description=long_description,
long_description_content_type="text/markdown",
url="https://github.com/Chimoney/chimoney-community-projects/tree/main/submissions/Chimoney-Python",
# download_url="", # TODO add download url
license="MIT",
packages=["chimoney"],
keywords=[
"Chimoney",
"Python",
"Chimoney-Python",
"Chimoney Python",
"Chimoney Python Wrapper",
],
classifiers=[
"Programming Language :: Python :: 3",
"License :: OSI Approved :: MIT License",
"Operating System :: OS Independent",
"Development Status :: 3 - Alpha",
"Intended Audience :: Developers",
"Topic :: Software Development :: Libraries :: Python Modules",
"Topic :: Software Development :: Libraries",
"Topic :: Software Development",
"Topic :: Utilities",
"Topic :: Internet",
],
install_requires=["requests"],
python_requires=">=3.6",
)
================================================
FILE: submissions/Chimoney-Python/tests/__init__.py
================================================
import os
import time
from unittest import TestCase, main
from chimoney import Chimoney, BaseAPI
test_chimoney_auth_key = os.environ.get("CHIMONEY_AUTH_KEY")
================================================
FILE: submissions/Chimoney-Slackbot/.gitignore
================================================
venv
temp.py
================================================
FILE: submissions/Chimoney-Slackbot/Readme.md
================================================
# CHIMONEY SLACKBOT
## Description
================================================
FILE: submissions/Chimoney-Slackbot/main.py
================================================
from dotenv import load_dotenv
import os
import argparse
load_dotenv()
parser = argparse.ArgumentParser(description="Chisend Slack Bot")
parser.add_argument(
"-ue",
"--use_env",
help="Use environment variables for the API keys",
action="store_true",
)
API_KEYS = {
"slack_key": "",
"chimoney_key": "",
}
if parser.parse_args().use_env:
API_KEYS["slack_key"] = os.getenv("SLACK_API_KEY")
def main():
# start web server process
p1 = multiprocessing.Process(target=web_server.start_server)
p1.start()
# get all the slack tokens from database
tokens = get_slack_tokens()
# start rtm process for each token
# check for new tokens every 5 minutes
while True:
time.sleep(300)
tokens = get_slack_tokens()
for token in tokens:
if token not in processes:
process = multiprocessing.Process(target=rtm.start_rtm, args=(token,))
process.start()
processes.append(process)
if __name__ == "__main__":
main()
================================================
FILE: submissions/Chimoney-Slackbot/utils/app/__init__.py
================================================
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
import os
from dotenv import load_dotenv
load_dotenv()
client_id = os.environ.get("SLACK_CLIENT_ID")
client_secret = os.environ.get("SLACK_CLIENT_SECRET")
oauth_scope = os.environ.get("SLACK_OAUTH_SCOPE")
basedir = os.path.abspath(os.path.dirname(__file__))
app = Flask(__name__)
app.config["SECRET_KEY"] = os.environ.get("SECRET_KEY", "omo")
app.config["SQLALCHEMY_DATABASE_URI"] = os.environ.get(
"DATABASE_URL", "sqlite:///" + os.path.join(basedir, "mydatabase.db")
)
db = SQLAlchemy(app)
app.config.from_object(__name__)
from app import views
================================================
FILE: submissions/Chimoney-Slackbot/utils/app/models.py
================================================
from app import db
class AccessToken(db.Model):
__tablename__ = "access_token"
id = db.Column(db.Integer, primary_key=True)
team_id = db.Column(db.String(255), unique=True, nullable=False)
access_token = db.Column(db.String(255), unique=True, nullable=False)
def __init__(self, team_id, access_token) -> None:
self.team_id = team_id
self.access_token = access_token
def __repr__(self) -> str:
return f"Team ID: {self.team_id}, Access Token: {self.access_token}"
def init_db():
db.create_all()
if __name__ == "__main__":
init_db()
================================================
FILE: submissions/Chimoney-Slackbot/utils/app/views.py
================================================
from app import app, db
from flask import render_template, request, redirect, url_for
from app.models import AccessToken
from slack_sdk.web import WebClient
import os
import logging
logging.basicConfig(level=logging.DEBUG)
client_id = os.environ.get("SLACK_CLIENT_ID")
client_secret = os.environ.get("SLACK_CLIENT_SECRET")
@app.route("/slack/install", methods=["GET"])
def oauth_redirect():
state = "randomly-generated-one-time-value"
return f"""
"""
@app.route("/slack/oauth_redirect", methods=["GET"])
def oauth_callback():
code = request.args.get("code")
client = WebClient()
print(code)
# response = client.oauth_v2_access(
# client_id=client_id,
# client_secret=client_secret,
# code=code,
# )
# oauth_scope v1 response
response = client.oauth_access(
client_id=client_id,
client_secret=client_secret,
code=code,
)
print(response)
access_token = response["bot"]["bot_access_token"]
team_id = response["team_id"]
# check if team_id already exists
all_tokens = get_all_access_token()
if all_tokens:
for token in all_tokens:
if token.team_id == team_id:
return "Already installed!"
db.session.add(AccessToken(team_id=team_id, access_token=access_token))
db.session.commit()
# team_id = response["team"]["id"]
# access_token = response["access_token"]
# db.session.add(AccessToken(team_id, access_token))
# db.session.commit()
return "Success!"
def get_all_access_token():
with app.app_context():
all_tokens = AccessToken.query.all()
return all_tokens
with app.app_context():
db.create_all()
print(get_all_access_token())
================================================
FILE: submissions/Chimoney-Slackbot/utils/bot.py
================================================
================================================
FILE: submissions/Chimoney-Slackbot/utils/collation.py
================================================
class SlackBot:
def __init__(self, api_key):
self.api_key = api_key
def handle_command(self):
pass
def parse_bot_command(self):
pass
def get_mentioned_user_email(self):
pass
def start_bot(self):
pass
================================================
FILE: submissions/Chimoney-Slackbot/utils/functions.py
================================================
import os
from chimoney import Chimoney
def get_user_email(client, user_id):
user = client.web_client.users_info(user=user_id)
return user["user"]["profile"]["email"]
def get_bot_id(client):
return client.web_client.auth_test()["user_id"]
def is_mention(client, event, bot_id=None):
if not bot_id:
bot_id = get_bot_id(client)
return event["text"].startswith(f"<@{bot_id}>")
def is_valid_command(client, event, bot_id=None):
if not bot_id:
bot_id = get_bot_id(client)
return event["text"].startswith(f"<@{bot_id}> send")
def send_chimoney(client, text):
# Split the tweet content
tweet_content = text.split()
# Get the amount and recipients
amount = tweet_content[2]
# remove <@ and > from the string
if "to" in tweet_content:
recipients = [recipient[2:-1] for recipient in tweet_content[4:]]
else:
recipients = [recipient[2:-1] for recipient in tweet_content[3:]]
checkout_value = []
for user_id in recipients:
print(user_id)
temp = {
"email": get_user_email(client, user_id),
"valueInUSD": int(amount),
}
checkout_value.append(temp)
print(checkout_value)
chimoney = Chimoney.set_api_key(os.getenv("CHIMONEY_API_KEY"))
task_status = chimoney.payouts.initiate_chimoney(checkout_value)
print(task_status)
if task_status[1] == 200:
# Get the payout link from the task status
payment_link = task_status[0]["data"]["paymentLink"]
chiRef = task_status[0]["data"]["data"][0]["id"]
response = {"payment_link": payment_link, "chiRef": chiRef}
return response
else:
return None
================================================
FILE: submissions/Chimoney-Slackbot/utils/rtm.py
================================================
import os
from slack_sdk.rtm_v2 import RTMClient
from dotenv import load_dotenv
import logging
import multiprocessing
from functions import is_valid_command, send_chimoney, is_mention
logging.basicConfig(level=logging.DEBUG)
load_dotenv()
def start_rtm(token):
rtm_client = RTMClient(token=token)
@rtm_client.on("message")
def print_events(client: RTMClient, event: dict):
# send a messenge to the user direct message
if is_valid_command(client, event):
print(event["text"])
response = send_chimoney(client, event["text"])
if response:
client.web_client.chat_postMessage(
channel=event["user"],
text=f"Payment link: {response['payment_link']}",
)
else:
client.web_client.chat_postMessage(
channel=event["user"],
text=f"Something went wrong, please try again later",
)
@rtm_client.on("message")
def handle(client: RTMClient, event: dict):
if "Hello" in event["text"]:
channel_id = event["channel"]
thread_ts = event["ts"]
user = event[
"user"
] # This is not username but user ID (the format is either U*** or W***)
client.web_client.chat_postMessage(
channel=channel_id, text=f"Hi <@{user}>!", thread_ts=thread_ts
)
return rtm_client.start()
def run_processes():
processes = []
for token in os.getenv("SLACK_TOKENS").split(","):
process = multiprocessing.Process(target=start_rtm, args=(token,))
process.start()
processes.append(process)
print(f"{len(processes)} processes started")
for process in processes:
process.join()
if __name__ == "__main__":
start_rtm(os.getenv("SLACK_CLIENT_TOKEN"))
================================================
FILE: submissions/Chimoney-Slackbot/utils/run.py
================================================
#! /usr/bin/env python
from app import app
app.run(debug=True, host="0.0.0.0", port=5050)
================================================
FILE: submissions/Chimoney-Slackbot-V2/.gitignore
================================================
data
.env
ngrok.exe
.pytest_cache
.idea
.vscode
*.pyc
*.pyo
*.pyd
__pycache__
*/__pycache__
*.so
================================================
FILE: submissions/Chimoney-Slackbot-V2/Dockerfile
================================================
FROM python:3.11-alpine
# Install system dependencies
RUN apk add --no-cache python3-dev libpq gcc musl-dev
# Path: /app
WORKDIR /app
# Path: /app/requirements.txt
COPY requirements.txt .
# Path: /app
RUN pip install -r requirements.txt
# Copy all files from current directory to /app in container
COPY . .
# Path: /app
CMD ["python", "slackbot.py"]
================================================
FILE: submissions/Chimoney-Slackbot-V2/README.md
================================================
# Chimoney Slack Bot
The Chimoney Slack Bot is a Python application designed to facilitate money transfers within a Slack workspace. Users can send money to other users via simple commands, and the bot handles the rest.
## Features
- Send money within your Slack workspace.
- Seamless integration with Slack's UI.
- Multi-workspace support with OAuth integration.
## Installation
To install your Slack bot using the provided link, follow these steps:
Click on the installation link: https://stingray-app-3r8tj.ondigitalocean.app/slack/install.
You'll be redirected to the installation page. Click "Install to Workspace" to start the installation process.
If prompted, log in to your Slack workspace.
Review the requested permissions and click "Allow." This will initiate the OAuth installation process.
After you click "Allow," the Slack bot will be installed in your workspace.
To start using your newly installed bot, simply mention it in a channel or use any slash commands or interactions it supports.
The Slack bot is now successfully installed and ready to assist in your Slack workspace.
### Requirements
Before installing the Chimoney Slack Bot, ensure you have the following:
- Python 3.9+
- A Slack workspace where you can install the bot.
- A [Chimoney](https://chimoney.io/) account with an API key.
- A Slack Application from [Slack API](https://api.slack.com/)
### Installation Steps
1. Clone this repository to your local machine:
2. Change into the project directory:
```shell
cd \submissions\Chimoney-Slackbot-V2\
```
3. Install project dependencies using pip:
```shell
pip install -r requirements.txt
```
4. Create a `.env` file in the project directory and set the following environment variables:
```env
SLACK_SIGNING_SECRET=your_slack_signing_secret
CLIENT_ID=your_slack_app_client_id
CLIENT_SECRET=your_slack_app_client_secret
OAUTH_REDIRECT_URI=your_oauth_redirect_uri
CHIMONEY_AUTH_KEY=your_chimoney_api_key
```
Replace the placeholders with your actual credentials.
5. Start the Chimoney Slack Bot:
```shell
python slackbot.py
```
6. The bot should now be running and listening for commands in your Slack workspace.
## Usage
To use the Chimoney Slack Bot, follow these steps:
1. Invite the bot to a channel or use a slash command.
2. Use the `/sendchimoney` command followed by the payment details. For example:
```
/sendchimoney $50 @username1 @username2
```
3. The bot will handle the payment process and provide you with a payment link.
## Multi-Workspace Support
The Chimoney Slack Bot inherently supports multi-workspace configurations. This means that the bot can be easily deployed and used in multiple Slack workspaces without complex modifications. The bot adapts to different workspaces, enabling you to expand your user base across various Slack communities.
It only needs to be deployed once and can be installed on any workspace using OAuth.
## Deploying the Slackbot(Optional)
This section provides detailed steps on deploying your Slackbot on different platforms: Render, AWS, and Heroku. Choose the platform that best suits your requirements.
### Deploying on Render
1. **Create an Account on Render**: If you don't have one already, sign up on [Render](https://render.com/) and log in.
2. **Create a New Web Service**:
- Choose a name for your service.
- Set your deployment region.
- Configure environment variables.
- Define the path to your Dockerfile and port.
- Click "Create Web Service."
3. **Connect Your GitHub Repository (Optional)**: If your code is hosted on GitHub, connect your repository to Render.
4. **Deploy Your Slackbot**:
- Click "Deploy" to initiate the deployment process.
- Render will build your Docker image, deploy it, and handle routing and SSL certificates.
- Once deployed, you'll receive a live URL for your Slackbot.
5. **Configure Slack and Test**:
- Set up your Slack App with the appropriate Redirect URL.
- Invite your Slackbot to desired channels.
- Test your Slackbot using the Render-provided live URL.
### Deploying on AWS
1. **Set Up an AWS Account**: Sign up for an AWS account on [AWS](https://aws.amazon.com/).
2. **Launch an EC2 Instance**:
- Use a Linux-based Amazon Machine Image (AMI).
- Configure security groups to allow traffic on the bot's port.
- Create and associate a key pair for access.
3. **Connect to Your EC2 Instance**: Use SSH to connect and upload your Slackbot code.
4. **Install Docker**:
- Update the instance and install Docker.
- Build and run your Slackbot container.
5. **Set Up a Domain (Optional)**: Configure Route 53 or another domain registrar to point to your EC2 instance's public IP.
6. **Configure Slack and Test**:
- Set up your Slack App with the appropriate Redirect URL.
- Invite your Slackbot to desired channels.
- Test your Slackbot using a custom domain or the EC2 instance's public IP.
### Deploying on Heroku
1. **Create a Heroku Account**: Sign up for a Heroku account at [Heroku](https://www.heroku.com/).
2. **Install the Heroku CLI**: Download and install the [Heroku CLI](https://devcenter.heroku.com/articles/heroku-cli).
3. **Prepare Your Slackbot**:
- Ensure you have a `Procfile` with appropriate content.
4. **Deploy to Heroku**:
- Open a terminal in your Slackbot directory.
- Log in to Heroku using `heroku login`.
- Create a new Heroku app using `heroku create`.
- Deploy your Slackbot with Git.
5. **Configure Slack and Test**:
- Set up your Slack App with the correct Redirect URL.
- Invite your Slackbot to desired channels.
- Test your Slackbot using the Heroku app's URL.
Choose the platform that best suits your needs and configuration preferences.
## License
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
## Acknowledgments
- [Chimoney](https://chimoney.io/) for their financial services integration.
================================================
FILE: submissions/Chimoney-Slackbot-V2/modules/choices.py
================================================
class ValidatorRegexFormats:
def __init__(self):
self._regex_formats = {
"same_ammount_single_or_multiple_users": r"^[$#]?\d+\s(@\w+\s*)+$",
"random_giveaway": r"random (\d+) (\d+)",
"random_giveaway_between_multiple_users": r"(\d+) ((?:<@\w+\s*)+)(\d+)",
}
def get_regex(self, regex_format):
return self._regex_formats[regex_format]
================================================
FILE: submissions/Chimoney-Slackbot-V2/modules/giveaway.py
================================================
from chimoney import Chimoney
import time
import random
from dotenv import load_dotenv
import os
from .sendchimoney import get_user_email_from_username
load_dotenv()
# Initialize Chimoney and set the API key
chimoney = Chimoney()
chimoney.set_api_key(os.getenv("CHIMONEY_AUTH_KEY"))
async def initiate_chimoney_async(checkout_values):
return chimoney.payouts.initiate_chimoney(checkout_values)
async def giveaway_with_tagged_users(client, text):
checkout_values = []
text_content = text.split()
number_of_winners = int(text_content[0])
paticipants = text_content[1:-1]
prize_pool = int(clean_amount(text_content[-1]))
prize = prize_pool / number_of_winners
# Checks if the opration is possible
if len(paticipants) < number_of_winners:
return None
winners = random.sample(paticipants, number_of_winners)
winners = [{"user_id": winner} for winner in winners]
for winner in winners:
# get winner's email from email
try:
winner["email"] = await get_user_email_from_username(
client, winner["user_id"]
)
# Add delay to avoid rate limiting
time.sleep(1)
except Exception as e:
print(f"Error looking up user {winner['user_id']}: {str(e)}")
# If the user is not found, remove them from the list of winners
winners.remove(winner)
for winner in winners:
checkout_values.append(
{
"email": winner["email"],
"valueInUSD": prize,
}
)
if not checkout_values:
return None
task_status = await initiate_chimoney_async(checkout_values)
if task_status[1] == 200:
# Get the payout link
payment_link = task_status[0]["data"]["paymentLink"]
chiRef = task_status[0]["data"]["data"][0]["id"]
return {
"payment_link": payment_link,
"chiRef": chiRef,
"winners": winners,
}
async def random_giveaway(client, text, channel_id):
"""
Randomly selects users from the channel to receive Chimoney.
The command contain the number of winners and the prize pool ammount.
The command must be in the format "random ".
"""
text_content = text.split()
number_of_winners = int(text_content[1])
prize_pool = int(clean_amount(text_content[2]))
checkout_values = []
# Get the list of users in the channel
users = await get_channel_users(client, channel_id=channel_id)
# Checks if the opration is possible
if len(users) < number_of_winners:
return None
# Randomly select winners
winners = random.sample(users, number_of_winners)
winners = [{"user_id": winner} for winner in winners]
# Get the email address of each winner
for winner in winners:
try:
winner["email"] = await get_user_email(client, winner["user_id"])
# Add delay to avoid rate limiting
time.sleep(1)
except Exception as e:
print(f"Error looking up user {winner['user_id']}: {str(e)}")
# If the user is not found, remove them from the list of winners
winners.remove(winner)
# Calculate the prize for each winner
prize = prize_pool / number_of_winners
# Send Chimoney to each winner
for winner in winners:
checkout_values.append(
{
"email": winner["email"],
"valueInUSD": prize,
}
)
if not checkout_values:
return None
task_status = await initiate_chimoney_async(checkout_values)
if task_status[1] == 200:
# Get the payout link
payment_link = task_status[0]["data"]["paymentLink"]
chiRef = task_status[0]["data"]["data"][0]["id"]
return {
"payment_link": payment_link,
"chiRef": chiRef,
"winners": winners,
}
else:
return None
def clean_amount(amount):
"""
Removes any non-numeric characters from the amount.
"""
return "".join([c for c in amount if c.isdigit()])
async def get_channel_users(client, channel_id):
"""
Gets a list of users in the channel.
"""
channel_info = await client.conversations_members(channel=channel_id, limit=1000)
users = channel_info["members"]
return users
async def get_user_email(client, user_id):
"""
Get the email address of a Slack user by user ID.
Args:
client (Slack WebClient): The Slack API client.
user_id (str): The user's Slack user ID.
Returns:
str or None: The user's email address, or None if the user is not found.
"""
try:
user_info = client.users_info(user=user_id)
return user_info["user"]["profile"]["email"]
except Exception as e:
print(f"Error looking up user {user_id}: {str(e)}")
return None
================================================
FILE: submissions/Chimoney-Slackbot-V2/modules/sendchimoney.py
================================================
from chimoney import Chimoney
import time
from dotenv import load_dotenv
import os
load_dotenv()
# Initialize Chimoney and set the API key
chimoney = Chimoney()
chimoney.set_api_key(os.getenv("CHIMONEY_AUTH_KEY"))
# Initialize a cache for user data, with separate caches for each workspace
workspace_user_caches = {}
cache_expiry_time = 3600 # Cache expires after 1 hour (adjust as needed)
# Initialize a cache for user_list data for each workspace
user_list_cache = {}
user_list_cache_timestamp = {}
user_list_cooldown = 300 # Cooldown time in seconds (adjust as needed)
async def initiate_chimoney_async(checkout_values):
return chimoney.payouts.initiate_chimoney(checkout_values)
async def send_chimoney(client, text, team_id):
"""
Send Chimoney to recipients based on a text command.
Args:
client (Slack WebClient): The Slack API client.
text (str): The command text.
Returns:
dict or None: A dictionary containing payment information, or None if there's an error.
"""
text_content = text.split()
print(text_content)
amount = clean_amount(text_content[0])
print(amount)
recipients = text_content[1:]
print(recipients)
checkout_values = []
for user_id in recipients:
try:
email = await get_user_email_from_username(client, user_id, team_id)
except Exception as e:
print(f"Error looking up user {user_id}: {str(e)}")
email = None
if email:
checkout_values.append(
{
"email": email,
"valueInUSD": int(amount),
}
)
if not checkout_values:
return None
task_status = await initiate_chimoney_async(checkout_values)
if task_status[1] == 200:
# Get the payout link from the task status
payment_link = task_status[0]["data"]["paymentLink"]
chiRef = task_status[0]["data"]["data"][0]["id"]
response = {"payment_link": payment_link, "chiRef": chiRef}
return response
else:
return None
def clean_amount(amount):
"""
Clean an amount by removing the $ or # symbol.
Args:
amount (str): The amount to clean.
Returns:
str: The cleaned amount.
"""
amount = amount.replace("$", "")
amount = amount.replace("#", "")
return amount.strip()
def get_user_email(client, user_id):
"""
Get the email address of a Slack user by user ID.
Args:
client (Slack WebClient): The Slack API client.
user_id (str): The user's Slack user ID.
Returns:
str or None: The user's email address, or None if the user is not found.
"""
try:
user_info = client.users_info(user=user_id)
return user_info["user"]["profile"]["email"]
except Exception as e:
print(f"Error looking up user {user_id}: {str(e)}")
return None
async def get_user_email_from_username(client, username, workspace_id):
username = clean_username(username)
# Check if the workspace has a cache
if workspace_id not in workspace_user_caches:
workspace_user_caches[workspace_id] = {}
workspace_cache = workspace_user_caches[workspace_id]
if username in workspace_cache:
email = workspace_cache[username].get("email")
if email:
return email
try:
current_time = time.time()
# Check if cooldown time has passed since the last user_list call
if (
workspace_id not in user_list_cache
or (current_time - user_list_cache_timestamp.get(workspace_id, 0))
>= user_list_cooldown
):
# Fetch and cache the user_list data for this workspace
response = await client.users_list()
# print(response["members"])
user_list_cache[workspace_id] = response["members"]
user_list_cache_timestamp[
workspace_id
] = current_time # Update the timestamp
# Populate the workspace cache with user data
for user in user_list_cache[workspace_id]:
try:
workspace_cache[user["name"]] = {
"email": user["profile"]["email"],
"timestamp": current_time,
}
except KeyError:
pass
if username in workspace_cache:
email = workspace_cache[username].get("email")
if email:
return email
return None
except Exception as e:
print(f"Error looking up user {username} in workspace {workspace_id}: {str(e)}")
return None
def clean_username(name):
"""
Clean a username by removing the @ symbol.
Args:
name (str): The username to clean.
Returns:
str: The cleaned username.
"""
name = name.replace("@", "")
return name.strip()
================================================
FILE: submissions/Chimoney-Slackbot-V2/modules/validators.py
================================================
import re
from .choices import ValidatorRegexFormats
def validate_sendchimoney_text(text):
# Check if the text is empty
if not text:
return False
# Check if the text is a valid format
regex_formats = ValidatorRegexFormats()
regex = regex_formats.get_regex("same_ammount_single_or_multiple_users")
if re.match(regex, text):
return True, "SASMU"
return False, "Invalid format"
def validate_giveaway_text(text):
# Check if the text is empty
if not text:
return False
# Check if the text is a valid format
regex_formats = ValidatorRegexFormats()
regex = regex_formats.get_regex("random_giveaway")
if re.match(regex, text):
return True, "RG"
regex = regex_formats.get_regex("random_giveaway_between_multiple_users")
if re.match(regex, text):
return True, "RGBMU"
return False, "Invalid format"
if __name__ == "__main__":
print(validate_sendchimoney_text("$100 @U01CZ1H2R7U"))
print(validate_sendchimoney_text("$100 @U01CZ1H2R7U @U01CZ1H2R7U"))
print(validate_sendchimoney_text("$100 @U01CZ1H2R7U @U01CZ1H2R7U @U01CZ1H2R7U"))
print(
validate_sendchimoney_text(
"$100 $100 $100 @U01CZ1H2R7U @U01CZ1H2R7U @U01CZ1H2R7U"
)
)
print(
validate_sendchimoney_text(
"$100 $100 $100 @U01CZ1H2R7U @U01CZ1H2R7U> @U01CZ1H2R7U> @U01CZ1H2R7U"
)
)
print(
validate_sendchimoney_text(
"$100 $100 $100 $100 $100 $100 $100 @U01CZ1H2R7U @U01CZ1H2R7U @U01CZ1H2R7U @U01CZ1H2R7U"
)
)
print(
validate_sendchimoney_text("100 @U01CZ1H2R7U 100 @U01CZ1H2R7U 100 @U01CZ1H2R7U")
)
================================================
FILE: submissions/Chimoney-Slackbot-V2/slackbot.py
================================================
from slack_bolt.oauth.async_oauth_settings import AsyncOAuthSettings
from slack_bolt.async_app import AsyncApp
import os
from slack_sdk.oauth.installation_store import FileInstallationStore
from slack_sdk.oauth.state_store import FileOAuthStateStore
from modules.validators import validate_sendchimoney_text, validate_giveaway_text
from sqlalchemy import create_engine
from modules.sendchimoney import (
send_chimoney as send_chimoney_response,
)
from modules.giveaway import random_giveaway, giveaway_with_tagged_users
import logging
logger = logging.getLogger(__name__)
from dotenv import load_dotenv
import os
load_dotenv()
# installation_store = sqlalchemy.SQLAlchemyInstallationStore(
# client_id=os.environ["CLIENT_ID"],
# engine=create_engine(os.environ["DATABASE_URL"]),
# logger=logger,
# )
# Initializes your app with your bot token and signing secret
SLACK_SIGNING_SECRET = os.environ["SLACK_SIGNING_SECRET"]
CLIENT_ID = os.environ["CLIENT_ID"]
CLIENT_SECRET = os.environ["CLIENT_SECRET"]
OAUTH_REDIRECT_URI = os.environ["OAUTH_REDIRECT_URI"]
# Initializes your Slack Client and Bolt App
# client = WebClient(token=SLACK_API_TOKEN)
app = AsyncApp(
signing_secret=SLACK_SIGNING_SECRET,
oauth_settings=AsyncOAuthSettings(
client_id=CLIENT_ID,
client_secret=CLIENT_SECRET,
scopes=["channels:read", "groups:read", "chat:write"],
installation_store=FileInstallationStore(base_dir="./data"),
state_store=FileOAuthStateStore(
expiration_seconds=600, base_dir="./data/oauth_states"
),
redirect_uri=OAUTH_REDIRECT_URI,
),
)
@app.command("/sendchimoney")
async def send_chimoney(ack, say, command, client, logger):
await ack()
logger.info(command)
try:
text = command["text"]
valid, text_type = validate_sendchimoney_text(text)
if valid:
if text_type == "SASMU":
send_chimoney_text = await send_chimoney_response(
client, text, command["team_id"]
)
if send_chimoney_text:
await client.chat_postMessage(
channel=command["user_id"],
text="Payment link: " + send_chimoney_text["payment_link"],
)
else:
await client.chat_postMessage(
channel=command["user_id"],
text="An error occurred while processing your request.",
)
else:
logger.info({"text": text, "valid": valid, "text_type": text_type})
await say(f"Error: {text_type}")
except Exception as e:
await say(f"An error occurred: {str(e)}")
@app.command("/giveaway")
async def giveaway(ack, say, command, client, logger):
await ack()
say("Processing your request...")
try:
text = command["text"]
valid, text_type = validate_giveaway_text(text)
if valid:
if text_type == "RG":
channel_id = command["channel_id"]
result = await random_giveaway(client, text, channel_id)
if result:
# Send Payment Link to the user that requested the giveaway
await client.chat_postMessage(
channel=command["user_id"],
text="Payment link: " + result["payment_link"],
)
# send a congratulatory message with all the winners tagged
winners_text = "Congratulations to "
for winner in result["winners"]:
winners_text += f"<@{winner['user_id']}> "
client.chat_postMessage(
channel=command["channel_id"],
text=winners_text,
)
else:
await client.chat_postMessage(
channel=command["user_id"],
text="An error occurred while processing your request.",
)
elif text_type == "RGBMU":
result = await giveaway_with_tagged_users(client, text)
if result:
# Send Payment Link to the user that requested the giveaway
await client.chat_postMessage(
channel=command["user_id"],
text="Payment link: " + result["payment_link"],
)
# send a congratulatory message with all the winners tagged
winners_text = "Congratulations to "
for winner in result["winners"]:
# winners are tagged with their @username
winners_text += f"@{winner['user_id']} "
client.chat_postMessage(
channel=command["channel_id"],
text=winners_text,
)
else:
await client.chat_postMessage(
channel=command["user_id"],
text="An error occurred while processing your request.",
)
else:
await say(f"Error: {text_type}")
else:
logger.info({"text": text, "valid": valid, "text_type": text_type})
await say(f"Error: {text_type}")
except Exception as e:
await say(f"An error occurred: {str(e)}")
@app.event("app_mention")
async def event_test(body, say, logger):
logger.info(body)
await say("What's up?")
# Start your app
if __name__ == "__main__":
app.start(port=int(os.environ.get("PORT", 3000)))
# SocketModeHandler(app, os.environ["SLACK_APP_TOKEN"]).start()
================================================
FILE: submissions/Chimoney-Slackbot-V2/tests/__init__.py
================================================
================================================
FILE: submissions/Chimoney-Slackbot-V2/tests/validator_tests.py
================================================
# test validators and functions
from pytest import mark
from modules import validators
# test validators
@mark.parametrize(
"test_input,expected",
[
("$100 <@U01CZ1H2R7U>", (True, "SASMU")),
("$100 <@U01CZ1H2R7U> <@U01CZ1H2R7U>", (True, "SASMU")),
("$100 <@U01CZ1H2R7U> <@U01CZ1H2R7U> <@U01CZ1H2R7U>", (True, "SASMU")),
("100 <@U01CZ1H2R7U>", (True, "SASMU")),
("100 <@U01CZ1H2R7U> <@U01CZ1H2R7U>", (True, "SASMU")),
("100 <@U01CZ1H2R7U> <@U01CZ1H2R7U> <@U01CZ1H2R7U>", (True, "SASMU")),
("#100 <@U01CZ1H2R7U>", (True, "SASMU")),
("#100 <@U01CZ1H2R7U> <@U01CZ1H2R7U>", (True, "SASMU")),
("#100 <@U01CZ1H2R7U> <@U01CZ1H2R7U> <@U01CZ1H2R7U>", (True, "SASMU")),
(
"100 <@U01CZ1H2R7U> 100 <@U01CZ1H2R7U> 100 <@U01CZ1H2R7U>",
(False, "Invalid format"),
),
(
"$100 $100 $100 <@U01CZ1H2R7U> <@U01CZ1H2R7U> <@U01CZ1H2R7U>",
(False, "Invalid format"),
),
],
)
def test_validate_sendchimoney_text(test_input, expected):
assert validators.validate_sendchimoney_text(test_input) == expected
================================================
FILE: submissions/Chisend/.gitignore
================================================
./venv
venv
__pycache__
*.pyc
*.pyo
*.pyd
*.so
*.egg-info
*.egg
*.egg-link
*.dist-info
*.egg-info
*.egg
*.egg-link
*.dist-info
*.egg-info
# PyCharm
.idea
# Local settings
settings.py
local_settings.py
# Local file
temp.py
================================================
FILE: submissions/Chisend/Dockerfile
================================================
FROM python:3.9-alpine
COPY bots/chisend.py /bots/
COPY bots/main.py /bots/
COPY bots/utils.py /bots/
COPY requirements.txt /tmp
RUN pip install -r /tmp/requirements.txt
WORKDIR /bots
CMD ["python", "main.py", "-ue"]
================================================
FILE: submissions/Chisend/README.md
================================================
# CHISEND TWITTER BOT
The Chisend Twitter Bot that send chimoney to a user when called by a tweet.
Live Demo: https://twitter.com/send_chimoney
Docker is supported.
## INFO
The bot is written in Python and uses the [Tweepy](https://www.tweepy.org/) library to interact with the Twitter API.
It uses the pychimoney library to send the chimoney.
## How to use
- Follow the bot on twitter
- Tweet the bot with the following format
- @chisendtest send amount to @username
- The bot will you a direct message for confirmation and checkout
- ChiSpend will send the amount to the user
FOR EXAMPLE
@chisendtest send 100 to @chisendtest
FOR multiple users
@chisendtest send 100 to @chisendtest, @chisendtest2
## DEMO PICTURES
Example of a tweet to the bot



## How to run
- Clone the repo
- Create a .env file with the following variables
- API_KEY
- API_SECRET
- BEARER_TOKEN
- ACCESS_TOKEN
- ACCESS_TOKEN_SECRET
- CHIMONEY_API_KEY
- SCREEN_NAME (is the twitter handle of the bot)
- Docker build -t chisend .
- Docker run -d chisend -e API_KEY= -e API_SECRET= -e BEARER_TOKEN= -e ACCESS_TOKEN= -e ACCESS_TOKEN_SECRET= -e CHIMONEY_API_KEY= -e SCREEN_NAME=
if the bot is not a developer account, you will need to use oauth-key-gen to get the keys
- cd into bots folder
- pip install -r requirements.txt
- set access_token, access_token_secret(get from twitter developer dashboard)
- python oauth-key-gen.py
- click the link and get the pin
- paste the pin in the terminal
- copy the access_token and access_token_secret and paste in the .env file
OR
- Create a virtual environment
- Install the requirements
- Run the ```python ./main.py -ue ``` command
to use the environment variables
- Run the ```python ./main.py ``` command
## TODO
- [x] Get a developer Twitter Account to test
- [x] Integrate with chimoney-py
- [x] Test the bot
- [ ] Deploy the bot
- [ ] Add a web interface to the bot
- [ ] Make sending Asynchronous using celery
- [ ] Add multi-user send
- [ ] Add More features
## BLOCKERS
- [x] Get a developer Twitter Account to test
- [x] Integrate with chimoney-py
- [x] Test the bot
================================================
FILE: submissions/Chisend/bots/chisend.py
================================================
import re
import tweepy
from utils import is_following
from chimoney import Chimoney
import logging
import time
# Set up logging
logging.basicConfig(
format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
level=logging.INFO,
handlers=[logging.FileHandler("chisend.log"), logging.StreamHandler()],
)
logger = logging.getLogger(__name__)
class ChiSend(object):
def __init__(
self,
api_key,
api_secret,
bearer_token,
access_key,
access_secret,
chimoney_api_key,
screen_name,
):
self.search_terms = ["@chisendtest"]
self.stream = self.MyStream(
bearer_token=bearer_token,
api_key=api_key,
api_secret=api_secret,
access_key=access_key,
access_secret=access_secret,
chimoney_api_key=chimoney_api_key,
screen_name=screen_name,
)
def clear_search_terms(self):
# make self.search_terms empty
self.search_terms = []
def add_search_term(self, term):
# Add a term to search_terms
self.search_terms.append(term)
def remove_search_term(self, term):
# Remove a term from search_terms
self.search_terms.remove(term)
def start_stream(self):
# Adding terms to search rules
# It's important to know that these rules don't get deleted when you stop the
# program, so you'd need to use stream.get_rules() and stream.delete_rules()
# to change them, or you can use the optional parameter to stream.add_rules()
# called dry_run (set it to True, and the rules will get deleted after the bot
# stopped running).
for term in self.search_terms:
self.stream.add_rules(tweepy.StreamRule(term))
# Starting stream
self.stream.filter(
tweet_fields=["referenced_tweets", "author_id", "id", "text"]
)
class MyStream(tweepy.StreamingClient):
def __init__(
self,
api_key,
api_secret,
bearer_token,
access_key,
access_secret,
chimoney_api_key,
screen_name,
):
self.client = tweepy.Client(
bearer_token, api_key, api_secret, access_key, access_secret
)
self.auth = tweepy.OAuth1UserHandler(
api_key, api_secret, access_key, access_secret
)
self.api = tweepy.API(self.auth)
super().__init__(bearer_token=bearer_token)
self.chimoney_api_key = chimoney_api_key
self.account_id = self.api.get_user(screen_name=screen_name).id
self.screen_name = screen_name
# Set up the message templates
self.messages = {
"not_following": f"Please follow @{self.screen_name} to use this bot",
"check_dm": "Please check your DMs for the payment link",
"wrong_format": (
"Please use the correct format to use this bot\n e.g."
"@{} send $10 to @thelimeskies \n"
"(see pin tweet for more info)"
),
"donation": "Thank you for your donation!",
"bot_error": "Sorry, there was an error with the bot. Please try again later",
"sucess": (
"Hello, this is a payment link for you. Please pay the amount "
"specified to the address specified. If you have any questions, "
"please contact @chimoney. \n"
"Payment Link: {}\n"
"ChiRef: {}"
),
}
def on_connect(self):
logging.info("Stream Started")
# handle disconnection errors
def on_exception(self, exception):
logging.error(exception)
return True
# wait for 20 seconds before reconnecting after an error
def on_timeout(self):
logging.error("Timeout, reconnecting")
time.sleep(20)
return True
def on_error(self, error):
logging.error(error)
if error == 420:
return False # returning False in on_error disconnects the stream
def on_disconnect(self):
logging.info("Stream Stopped")
def send_tweet(self, tweet, reply_id):
"""
This function sends a tweet
Args:
tweet (str): The tweet to be sent
Returns:
None
"""
self.api.update_status(
status=tweet,
in_reply_to_status_id=reply_id,
auto_populate_reply_metadata=True,
)
logging.info("Tweet sent to {}".format(reply_id))
def send_dm(self, user_id, message):
"""
This function sends a direct message to the user who mentioned the bot
Args:
tweet (dict): The tweet that passed the stream
Returns:
None
"""
# Send a direct message to the user who mentioned the bot
try:
self.api.send_direct_message(user_id, message)
logging.info("Direct Message sent to {}".format(user_id))
except:
logging.error("Error sending direct message")
def perform_task(self, tweet_content):
# Split the tweet content
tweet_content = tweet_content.split()
# Get the task name
task_name = tweet_content[1]
# Get the amount and recipients
amount = tweet_content[2]
# Get the recipients
if "to" in tweet_content:
recipients = tweet_content[tweet_content.index("to") + 1 :]
else:
recipients = tweet_content[3:]
# Perform the task
if task_name == "send":
# Call pychimoney payout initiate function
chimoney = Chimoney.set_api_key(self.chimoney_api_key)
checkout_value = []
# check if ammount contains a dollar sign
if "$" in amount:
amount = amount.replace("$", "")
for recipient in recipients:
temp = {
"twitter": recipient,
"valueInUSD": int(amount),
}
checkout_value.append(temp)
task_status = chimoney.payouts.initiate_chimoney(
chimoneys=checkout_value
)
# check is the response is a success
if task_status[1] == 200:
# Get the payout link from the task status
payment_link = task_status[0]["data"]["paymentLink"]
chiRef = task_status[0]["data"]["data"][0]["id"]
response = {"paymentLink": payment_link, "chiRef": chiRef}
return response
else:
return None
def on_tweet(self, tweet):
"""
This function gets called when a tweet passes the stream
Args:
tweet (dict): The tweet that passed the stream
Returns:
None
"""
logging.info("Tweet received: {}".format(tweet["text"]))
# regex to check if the tweet is a reply
# replace @send_chimoney with the value of your bot's screen name
reply_regex = re.compile(rf"^\@{re.escape(self.screen_name)}")
# regex to check if the tweet follows the correct format for the bot
# @chisendtest send 10 @user1 @user2 @user3
# @chisendtest send $10 to @user1 @user2 @user3
# @chisendtest send 10 to @user1 @user2 @user3
# @chisendtest send $10 @user1 @user2 @user3
correct_regex = [
re.compile(
rf"^\@{re.escape(self.screen_name)}\s+send\s+\$?\d+\s+to\s+\@\w+(\s+\@\w+)*"
),
re.compile(
rf"^\@{re.escape(self.screen_name)}\s+send\s+\$?\d+\s+\@\w+(\s+\@\w+)*"
),
re.compile(
rf"^\@{re.escape(self.screen_name)}\s+send\s+\$?\d+\s+to\s+\@\w+(\s+\@\w+)*"
),
re.compile(
rf"^\@{re.escape(self.screen_name)}\s+send\s+\$?\d+\s+\@\w+(\s+\@\w+)*"
),
]
# if it's a reply check if it follows the correct format
if reply_regex.match(tweet["text"]):
if correct_regex[0].match(tweet["text"]) or correct_regex[1].match(
tweet["text"]
):
logging.info("Tweet is in the correct format")
if is_following(
self.api, tweet["author_id"], self.account_id
): # check if the user is following the bot
user_id = tweet["author_id"]
tweet_content = tweet["text"]
# Perform the task
task_status = self.perform_task(tweet_content)
# Check if the task was successful
if task_status:
# Get the payment link
payment_link = task_status["paymentLink"]
chiRef = task_status["chiRef"]
# Send the payment link to the user
message = self.messages["sucess"].format(
payment_link, chiRef
)
self.send_dm(user_id, message)
self.send_tweet("Check Your DM", tweet["id"])
else:
# Send a message to the user
message = "There was an error performing the task"
self.send_dm(user_id, message)
self.send_tweet("Check Your DM", tweet["id"])
elif not is_following(
self.api, tweet["author_id"], self.account_id
):
self.send_tweet(self.messages["not_following"], tweet["id"])
else:
self.send_tweet(
self.messages["wrong_format"].format(self.screen_name),
tweet["id"],
)
else:
logging.info("Tweet is not a reply")
================================================
FILE: submissions/Chisend/bots/entrypoint.sh
================================================
#!/bin/bash
set -e
# Run the bot
python3 -m main.py
# Run the bot in debug mode
# python3 -m main.py --debug
================================================
FILE: submissions/Chisend/bots/main.py
================================================
#!/usr/bin/env python3
from dotenv import load_dotenv
import os
import argparse
from chisend import ChiSend
load_dotenv()
parser = argparse.ArgumentParser(description="Chisend Bot")
parser.add_argument(
"-ue",
"--use_env",
help="Use environment variables for the API keys",
action="store_true",
)
# create logs folder if it doesn't exist
if not os.path.exists("logs"):
os.mkdir("logs")
KEYS = {
"api_key": "",
"api_secret": "",
"bearer_token": "",
"access_key": "",
"access_secret": "",
"chimoney_api_key": "",
"screen_name": "",
}
# check if the user wants to use environment variables
if parser.parse_args().use_env:
load_dotenv()
# get the keys and tokens from the .env file
KEYS["api_key"] = os.getenv("API_KEY")
KEYS["api_secret"] = os.getenv("API_SECRET")
KEYS["bearer_token"] = os.getenv("BEARER_TOKEN")
KEYS["access_key"] = os.getenv("ACCESS_KEY")
KEYS["access_secret"] = os.getenv("ACCESS_SECRET")
KEYS["chimoney_api_key"] = os.getenv("CHIMONEY_API_KEY")
KEYS["screen_name"] = os.getenv("SCREEN_NAME")
# create an instance of ChiSend
chisend = ChiSend(
api_key=KEYS["api_key"],
api_secret=KEYS["api_secret"],
bearer_token=KEYS["bearer_token"],
access_key=KEYS["access_key"],
access_secret=KEYS["access_secret"],
chimoney_api_key=KEYS["chimoney_api_key"],
screen_name=KEYS["screen_name"],
)
term = "@" + KEYS["screen_name"] # type: ignore
chisend.clear_search_terms()
# add a search term
chisend.add_search_term([term])
chisend.start_stream()
================================================
FILE: submissions/Chisend/bots/oauth-key-gen.py
================================================
# 3 legged OAuth
import tweepy
oauth1_user_handler = tweepy.OAuth1UserHandler(
"access-token", "access-secret", callback="oob"
)
print(oauth1_user_handler.get_authorization_url(signin_with_twitter=True))
verifier = input("Input PIN: ")
access_token, access_token_secret = oauth1_user_handler.get_access_token(verifier)
# store access_token and access_token_secret somewhere safe
with open("access_token.txt", "w") as f:
f.write(access_token)
f.write("\n")
f.write(access_token_secret)
================================================
FILE: submissions/Chisend/bots/utils.py
================================================
def is_following(api: object, id_1: int, id_2: int) -> bool:
result = api.get_friendship(source_id=id_1, target_id=id_2)[0] # type: ignore
return result.following
================================================
FILE: submissions/Chisend/requirements.txt
================================================
certifi==2022.9.24
charset-normalizer==2.1.1
chimoney-py==0.0.2
flake8==5.0.4
idna==3.4
mccabe==0.7.0
oauthlib==3.2.1
pycodestyle==2.9.1
pyflakes==2.5.0
python-dotenv==0.21.0
requests==2.28.1
requests-oauthlib==1.3.1
tweepy==4.10.1
urllib3==1.26.12
================================================
FILE: submissions/Dev focused articles/top-3-payment-challenges-solutions-ifeoluwa-favour
================================================
# **Top 3 Challenges Companies Face When Paying Freelancers Globally (And How to Solve Them)**
by **Ifeoluwa Favour**
The freelance economy has experienced a boom in the last five years as COVID-19 measures greatly influenced the freelance economy by leading to a rise in remote work, making businesses become familiar with hiring remote workers.
The surging numbers tell the story. Over one-third of the U.S. workforce identifies as independent workers according to [Wripple](https://www.wripple.com/insights/wripples-2024-team-up-report-highlights). The [Dutch Chamber of Commerce (KvK)](https://www.kvk.nl/en/) says that the number of freelancers in the Netherlands has increased by 85% over the past decade. Today, the Netherlands is home to 1.6 million freelancers.
The freelance economy is constantly evolving. However, it has its benefits as well as challenges. One of those challenges is making international payments to freelancers. From regulatory compliance to payment delays to high cost of transfer fees, this is a challenge many companies need to overcome to benefit from the global talent pool of freelancers.
This article discusses challenges companies face when making payments to freelancers globally and how to solve these challenges.
## **Top 3 Challenges Companies Face When Paying Freelancers Globally**
1. **Regulatory compliance**
In order to prevent issues such as fraud, and maintain transparency in financial dealings, every country has set financial regulations that govern international payments.
A slight mistake in adherence to these regulations can result in substantial fines. For instance, in 2023, [JPMorgan Chase faced a $98.2 million penalty](https://www.federalreserve.gov/newsevents/pressreleases/enforcement20240314a.htm) for inadequate monitoring of firm and client trading activities, including failure to adhere to international payment and tax regulations.
2. **High Transfer Fees**
Transferring money to different countries can incur extra costs like high processing fees. Sometimes $300 payments can cost up to $60 in commissions.
The cost of transfer fees usually depends on the solution used to make the payment transfers. The best payment option will save your business extra unnecessary costs.
3. **Slow Transaction Time**
Timely payments are also an issue. Depending on the method of transfer, payments can take anywhere from 24 hours to even 5 days to process, and if the sum is big, freelancers get worried about fraud or non-payment, hurting the company's or business' reputation.
Newer payment options now significantly reduce the time freelancers have to wait to receive payment, relieving both the company or business and the freelancers of unnecessary troubles.
## **How Chimoney Solves Companies' Payment Challenges To Freelancers**
[Chimoney](https://chimoney.io/) is a payment platform for secure and efficient cross-border payments, multi-currency wallets, and global payouts.
As seen above, managing cross-border payments comes with a few challenges. Chimoney API is designed to solve the above challenges and more:
- **Regulatory Compliance:** Chimoney's API is designed with built-in compliance checks. It ensures that all transactions adhere to the regulatory requirements of each country involved.
- **Cost-Effective Transactions:** Chimoney's API offers competitive exchange rates and low transaction fees, helping businesses save on costs associated with cross-border payments.
- **Fast Processing Times:** Chimoney's API enables quick processing of cross-border transactions, significantly reducing the time it takes to transfer funds to freelancers.
- **Multiple Payment Methods:** Chimoney's API supports a wide range of payment methods, allowing businesses to cater to the preferences of freelancers.
- **Currency Conversion:** Chimoney's API offers real time currency conversion rates, providing accurate and transparent exchange rates.
Chimoney makes it simple for businesses to pay for and send international payments to freelancers globally with the Platform and API.
To get started with Chimoney Platform for instant payments, follow these steps:
- Create an account via the [Chimoney Website](https://chimoney.io/)
- Complete onboarding and KYC/KYB and subscribe to one of [our Plans](https://chimoney.io/pricing)
- Fund your account with Card, Wire/ACH, Interac and other methods
- Go to the [dash.chimoney.io/send](https://dash.chimoney.io/send) to pay anyone in the world using just their phone number or email
Alternatively, you can integrate Chimoney's API into your business to simplify your cross-border payment processes. For a detailed walkthrough, please refer to this post on [Integrating Chimoney's Global Payouts API](https://chimoney.io/blogs/the-ultimate-guide-to-simplifying-global-payouts-for-your-business-with-api-solutions/).
## **Conclusion**
Global payments to freelancers don't have to be challenging for companies. Regulatory compliance, slow transaction times, and high transfer fees can hinder companies' business operations and impact freelancer satisfaction.
However, Chimoney offers an effective solution by ensuring compliance with financial regulations, speeding up transfers, and reducing costs. By leveraging Chimoney, companies can overcome these obstacles and provide seamless, efficient payments to their freelancers, enabling stronger working relationships and boosting overall productivity.
================================================
FILE: submissions/FAQs/FAQs.md
================================================
# Chimoney Developer Toolkit - Frequently Asked Questions (FAQs)
Welcome to the Chimoney Developer Toolkit FAQ page! Here, you'll find answers to common questions, troubleshooting tips, and best practices for using the Chimoney API. Our goal is to help you integrate, secure, and use Chimoney's API efficiently.
---
## Table of Contents
- [General Questions](#general-questions)
- [Authentication and Security](#authentication-and-security)
- [Integration and Usage](#integration-and-usage)
- [Error Handling](#error-handling)
- [Support and Community](#support-and-community)
- [Other Common Questions](#other-common-questions)
---
## General Questions
### What is Chimoney API?
The **Chimoney API** allows developers to integrate payment and reward services into their applications. You can send payments globally, exchange rewards, and facilitate financial transactions via a unified platform.
For more details, refer to our [API Overview](https://chimoney.readme.io/reference/introduction).
### How do I get started with Chimoney API?
To get started with Chimoney API:
1. **Sign up** on [Chimoney's Developer Portal](https://dash.chimoney.io/auth/signin).
2. Review the [API Documentation](https://chimoney.readme.io/reference/introduction) to understand the available endpoints.
3. Obtain an API key and begin integrating with your platform using our SDKs or direct API calls.
For a detailed guide, check the [Getting Started Guide](https://chimoney.readme.io/reference/getting-started-with-your-api).
### Where can I find the API documentation?
You can find the full API documentation, including endpoints, SDKs, and integration examples, on our [API Documentation Page](https://chimoney.readme.io/reference/introduction).
---
## Authentication and Security
### How to obtain an API key?
To obtain an API key:
1. Log in to your [Chimoney account](https://dash.chimoney.io/auth/signin).
2. Navigate to the **API keys** section in your dashboard.
3. Generate a new API key.
For step-by-step instructions, refer to [API Key Setup](https://chimoney.readme.io/reference/authentication).
### How to manage and rotate API keys?
It's important to rotate your API keys periodically for security purposes. To manage your API keys:
1. Go to the **API keys** section in your account dashboard.
2. You can revoke, regenerate, or create new keys as needed.
### Best practices for securing API keys
Here are a few best practices for securing your API keys:
- **Never hard-code API keys** into your source code.
- **Use environment variables** to store API keys.
- **Rotate API keys** regularly and remove unused keys.
- **Monitor usage** to detect any suspicious activity.
---
## Integration and Usage
### What are the SDKs available for Chimoney API?
Chimoney provides SDKs in multiple programming languages to simplify the integration process:
- **Javascript(NPM) SDK**
- **Python SDK**
- **PHP-Laravel**
- **Flutter**
- **DotNet**
- **Java**
- **Rust**
You can find the full list of SDKs and their usage instructions on the [Libraries & Plugins](https://chimoney.readme.io/reference/libraries-plugins).
### How to integrate Chimoney API with different platforms?
You can integrate Chimoney API with various platforms like **web apps**, **mobile apps**, and **backend services** by following our platform-specific guides:
- **Web**: Use our JavaScript SDK or REST API.
- **Mobile**: Integrate via REST API with backend services.
- **Backend**: Use our server-side SDKs or directly call our API.
For detailed platform integration examples, visit our [Integration Guides](https://chimoney.readme.io/reference/integration-guides).
---
## Error Handling
### How to handle common API errors?
Chimoney API uses standard HTTP response codes to indicate errors. Here are some common errors and their resolutions:
- **400 Bad Request**: Invalid request. Check your request parameters.
- **401 Unauthorized**: Authentication failed. Verify your API key.
- **403 Forbidden**: You don't have permission to access this resource.
- **404 Not Found**: The requested resource doesn't exist.
- **500 Internal Server Error**: Something went wrong on our end. Try again later.
---
## Support and Community
### How can I get support if I encounter issues?
If you encounter any issues while using the Chimoney API, you can:
- Contact [support@chimoney.io](mailto:support@chimoney.io) to ask questions.
- Join our developer community on [Discord](https://discord.com/invite/Q3peDrPG95) to get support if you encounter issues.
You can also reach out to us via email at [support@chimoney.io](mailto:support@chimoney.io).
### How can I contribute to the Chimoney community?
We welcome contributions to improve Chimoney! You can contribute by:
- Reporting issues or suggesting features on our [GitHub Repository](https://github.com/chimoney).
- Sharing your integration stories and code samples with the community.
- Joining our developer community on [Discord](https://discord.com/invite/Q3peDrPG95) to collaborate and discuss new ideas.
---
## Other Common Questions
### What are the rate limits for Chimoney API?
Chimoney API has rate limits to ensure fair usage and stability. The rate limits depend on your subscription plan. For details on rate limits, check the [Pricing and benefits](https://chimoney.io/pricing/).
### How can I test Chimoney API without sending real transactions?
You can test the Chimoney API using our **sandbox environment**, which simulates real transactions without affecting actual accounts. To access the sandbox environment, follow the instructions in our [Testing Guide](https://chimoney.readme.io/reference/sandbox-environment).
---
Have more questions? Feel free to explore our [documentation](https://chimoney.readme.io/reference/introduction) or reach out to our support team for personalized assistance.
================================================
FILE: submissions/GetStarted/Blogs.html
================================================
Document
introduction to Chimoney
Chimoney is an Automated Global Payouts Platform. The Chimoney API is designed
for developers and companies, facilitating platform users to redeem airtime, cash, and more through the API. Additionally,
the Chimoney API offers payout functionalities for banks, airtime, mobile
money (momo), gift cards, and other services. Chimoney's Developer API
empower businesses with a robust API platform for seamless integration of
payment functionalities, enabling them to unlock global payment capabilities
and enhance their financial operations.
Access to Power-Packed Features:
A developer account grants access to a suite of potent API by Chimoney. These API encompass functionalities vital for a wide array of applications, spanning financial transactions to seamless data retrieval.
Real-time Testing and Integration:
Gain the ability to test APIs in real-time using the provided sandbox environment within the developer portal. This empowers you to comprehend API behavior, fine-tune integration, and ensure smooth functionality.
Customized Solutions:
With a developer account, you will explore Chimoney's API and pinpoint those aligning with your application's unique requirements. Tailor your integration for optimal outcomes.
In-depth Guides and Documentation:
Inside the developer portal, discover comprehensive documentation and guides offering profound insights into effective API utilization. These resources empower developers, including novices, to navigate through the integration seamlessly.
Enhanced Security and Authentication:
The developer account provides a unique API key, a secure identifier linked to your account. This key is vital for authenticating your API requests, ensuring only authorized users access the APIs.
Efficient Error Handling and Troubleshooting:
Integration through a developer account streamlines error handling and troubleshooting. Detailed error messages and status codes received through API responses expedite issue diagnosis and resolution.
Community Synergy and Assistance:
Engage with fellow developers, share experiences, and seek assistance within the developer community through your developer account. This collaborative environment enriches the integration process and fosters knowledge sharing.
Seamless Scalability and Growth:
As your application evolves and scales, a developer account facilitates easy adaptation and integration of new features and functionalities offered by Chimoney APIs. This scalability ensures your application stays current and competitive in the market.
for one to get started with the chimoney api one needs to create a developer account in order to access the apis and the developer portal which contains of the sandbox which allows one to test the apis
it also has documentation,
Documentation that guide the users on how to get started.
fill all the personal information then head on and fill the organisation information and also verify your organisation and personal details. you will be asked to provide either your national id or passport you can skip this part if you are a student and still doesnot have any of them
Then you will be directed to this page where you will have tabs like the dashboard, payments, organisations, earn, transcations and the developers tab
To create a developer portal click the developer pane of the side navigation bar
Developer portal
Then add a new application and give your application a name and an api key will be generated.
API Key Usage:
the api key is to be used in the authorization part with the key as Header and the api key as the value
Overview of Developer Portal:
Inside the developer portal, you'll find comprehensive documentation and guides that provide insights into using the API effectively. These resources empower developers, including beginners, to navigate through the integration process seamlessly.
Enhanced Security and Authentication:
Introduction to chimoney API
Endpoints give access to Powerful Features:
endpoints unlocks access to a suite of powerful API provided by Chimoney. These API endpoints offer functionalities crucial for a wide range of applications, from financial transactions to data retrieval.
significance of the sandbox for testing APIs in a safe environment.
Real-time Testing and Integration:
the sandbox is a vital tool for developers, providing a secure, controlled, and controlled environment for testing API.
It ensures that developers can validate their integration code,
understand API behavior, and develop robust applications without any impact on real user data or transactions.
This is instrumental in building reliable and high-quality applications that deliver value to end-users.
With a developer account, you gain the ability to test API in real-time using the sandbox environment provided in the developer portal. This allows you to understand API behavior, fine-tune integration, and ensure smooth functionality.
Tailored Solutions: Access the Sandbox
and test your api endpoints
Knowing the API you can explore the API Chimoney offers and identify the ones that align with your specific application needs. This allows you to tailor your integration for optimal results.
Account The api endpoints are self explanatory they tell the user what they are used
for eg the "get list of all supported airtime Countries" this will return the
countrues that are airtime supported this uses the POST method except for the
DELETE which uses a delete method
================================================
FILE: submissions/GetStarted/README.md
================================================
I have translated the blog post from HTML to Markdown.
================================================
FILE: submissions/GetStarted/style.css
================================================
/* :root {
color: aliceblue;
} */
.title h2 {
color: white;
font-size: larger;
font-size: 30px;
text-align: center;
background-color: purple;
}
================================================
FILE: submissions/Proposed-Chimoney-Copy/ChimoneyUXCopy.md
================================================
Chimoney Updated Copy.
Section 1
Old navbar links: Benefits, Products, About, Testimonials
New navbar links: Why choose Chispend?, Our features, About us, Our customer stories
Old heading: Unleash utility and engagement with one simple integration.
New heading: Shop and spend from your crypto wallet - your crypto, your way!
Old subheading: It's happening! You can buy gift cards, airtime, and more with tokens and NFTs in your wallet, app or protocol.
New subheading: Chispend lets you buy gift cards, airtime, and more with tokens and NFTs in your wallet, app, or protocol.
Old CTA button1: Integrate Chispend
New CTA button1: Chispend Integration
Old CTA button2: Spend your tokens
New CTA button2: Start spending
Comment: In my opinion, I don’t think the text carousel is necessary.
Section 2
Old heading: None
New heading: Multi-platform support
Old subheading: None
New subheading: Chispend has got you covered with a suite of crypto wallets to choose from. Select your preference and start shopping.
Card 1: Xumm wallet
Old CTA button: Use Xumm
New CTA button: Use Xumm Now or Start Shopping Now
Card 2: Metamask
Old CTA button: Use Metamask
New CTA button: Use Metamask Now or Start Shopping Now
Card 3: Chimoney
Old CTA button: Use Chimoney
New CTA button: Use Chimoney Now or Start Shopping Now
Comment: I broke down this section(section 2) into three - our features(section 2), more apps(section 3), and coming soon(section 4).
Reason: The UI looked too cluttered on the desktop view and one might get easily confused. Also, on mobile view, they just appeared like a standalone bunch of cards.
Suggestion: The UI needs to be improved so that those cluttered cards would be present in individual sections.
Section 3
Old heading: None
New heading: More Apps
Old subheading: None
New subheading: More apps to make your shopping experience even merrier.
Card 1: Valora
Comment: This could also be in the form of a card and the text being a CTA i.e Valora
Card 2: Status
Comment: This could also be in the form of a card and the text being a CTA i.e Status
Card 3: BSC EVM Wallets
Comment: This could also be in the form of a card and the text being a CTA i.e BSC EVM Wallets
Card 4: ETH Wallets
Comment: This could also be in the form of a card and the text being a CTA i.e ETH Wallets
Card 5: Polygon Wallets
Comment: This could also be in the form of a card and the text being a CTA i.e Polygon Wallets
Section 4
Old heading: None
New heading: Coming soon
Old subheading: None
New subheading: Stay tuned as we include more options just for you.
Card 1: Coinbase
Comment: This could also be in the form of a card and the text being a CTA i.e Coinbase
Card 2: Binance
Comment: This could also be in the form of a card and the text being a CTA i.e Binance
Card 3: Luno
Comment: This could also be in the form of a card and the text being a CTA i.e Luno
Card 4: Edge
Comment: This could also be in the form of a card and the text being a CTA i.e Edge
Comment: In my opinion, I don’t think the text carousel is necessary.
Section 5
Old heading: None
New heading: Why choose Chispend?
Card 1
Old heading: Off-ramps
New heading: Enjoy seamless transactions.
Old CTA button: Connect and spend
New CTA button: Get started
Card 2
Old heading: Only one integration
New heading: Simple and rapid integration
Old CTA button: Build in minutes
New CTA button: Start building
Card 3
Old heading: Embeddable and customizable style
New heading: Customize your wallet to taste
Old CTA button: Create your own
New CTA button: Style your wallet
Card 4
Old heading: Low code option
New heading: Low-code solution
Old CTA button: Try it now
New CTA button: Install Now.
Comment: In my opinion, I don’t think the text carousel is necessary.
Section 6
This section looks good.
Comment: In my opinion, I don’t think the text carousel is necessary.
Section 7
Old heading: None
New heading: Our customer stories
Old subheading: Embeddable shopping experience everyone loves
New subheading: Nil
Chispend old tag: Send and receive exactly what's needed.
Chispend new tag: Shopping with crypto made 10X easier.
General comments
The UI needs to be configured for the clarity of ideas.
The text carousel at the end of the sections is not necessary, they are distracting. And if any is to be used they can be just one or two.
The cards can be in carousel states instead of the text.
Inspiration
linumlabs.com
================================================
FILE: submissions/chiconnect-bank-api-payout/.gitignore
================================================
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*
node_modules
dist
dist-ssr
*.local
# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
.env
================================================
FILE: submissions/chiconnect-bank-api-payout/README.md
================================================
# Chiconnect bank-api-payout
A mini project to demonstrate integration of Chiconnect bank api payout using React framework.
## Setup
- `git clone `
- `cd project-name`
- `npm install`
- create a file in root directory with `.env` as the name and add the API key in this format VITE_API_KEY='api key'`
- `npm run dev`
## Commit style guidelines
A commit message should easily convey what it contains so this guidelines shows a commit should be for this project.
The commit message should be in this format `type: subject` where `type` can be any one of these:
- `feat: a new feature`
- `fix: a bug fix`
- `docs: changes to documentation`
- `style: formatting, missing semi colons, etc; no code change`
- `refactor: refactoring production code`
- `test: adding tests, refactoring test; no production code change`
- `chore: updating build tasks, package manager configs, etc; no production code change`
and the `subject` should be no greater than 50 characters, should begin with an uppercase and should use imperative tone. E.g: 'change'; not 'changed' or 'changes'
================================================
FILE: submissions/chiconnect-bank-api-payout/index.html
================================================
Chiconnect
================================================
FILE: submissions/chiconnect-bank-api-payout/package.json
================================================
{
"name": "chiconnect-api-payout",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "vite build",
"preview": "vite preview",
"preinstall": "npx npm-force-resolutions"
},
"dependencies": {
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-scripts": "^5.0.1"
},
"devDependencies": {
"@types/react": "^18.0.17",
"@types/react-dom": "^18.0.6",
"@vitejs/plugin-react": "^2.1.0",
"autoprefixer": "^10.4.12",
"dotenv": "^16.0.3",
"postcss": "^8.4.17",
"react-error-overlay": "^6.0.9",
"tailwindcss": "^3.1.8",
"vite": "^3.1.0"
},
"resolutions": {
"//": "See https://github.com/facebook/create-react-app/issues/11773",
"react-error-overlay": "6.0.9"
}
}
================================================
FILE: submissions/chiconnect-bank-api-payout/postcss.config.cjs
================================================
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
}
================================================
FILE: submissions/chiconnect-bank-api-payout/src/App.jsx
================================================
import { useEffect, useState } from "react";
import { API_KEY, getBanks } from "./service/fetchApi";
import chimoneyLogo from './assets/chimoney-logo.svg';
function App() {
const [error, setError] = useState('');
const [info, setInfo] = useState('');
const [banks, setBanks] = useState([]);
const [loading, setLoading] = useState(false);
const [paymentData, setPaymentData] = useState({
bank: '',
accountNumber: '',
amount: ''
});
const handleFormChange = (event) => {
const { name, value } = event.target;
setPaymentData(prevData => ({
...prevData,
[name]: value
}));
};
const handlePayClick = async (event) => {
event.preventDefault();
// Input Validation
if (paymentData.bank.length === 0) {
setError('Please select a valid bank.');
return;
}
if (paymentData.accountNumber.length === 0) {
setError('Please enter a valid account number.');
return;
}
if (isNaN(Number(paymentData.amount)) || Number(paymentData.amount) < 1) {
setError('Amount must be at least $1.');
return;
}
setError('');
setInfo('Please wait while the payment is being processed...');
setLoading(true);
// API Request to Chimoney
try {
const response = await fetch('https://api.chimoney.io/v0.2/payouts/bank', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-API-KEY': API_KEY
},
body: JSON.stringify({
banks: [{
countryToSend: 'Nigeria',
account_bank: paymentData.bank,
account_number: paymentData.accountNumber,
valueInUSD: Number(paymentData.amount)
}]
})
});
const data = await response.json();
const chimoneys = data?.data?.chimoneys;
if (chimoneys && chimoneys.length > 0) {
const successInfo = `${chimoneys[0].valueInUSD} USD has been successfully sent to account number ${chimoneys[0].account_number}`;
setInfo(successInfo);
} else {
setError("Transaction failed. Please try again.");
}
} catch (err) {
console.error(err);
setError("Something went wrong. Please try again.");
} finally {
setLoading(false);
}
};
useEffect(() => {
const fetchBanks = async () => {
try {
const data = await getBanks();
setBanks(data);
} catch (err) {
console.error(err);
setError("Failed to load banks. Please refresh the page.");
}
};
fetchBanks();
}, []);
return (
Bank
Account number
Amount (USD)
{
error && {error}
}
{
info && {info}
}
Powered by Chimoney
);
}
export default App;
================================================
FILE: submissions/chiconnect-bank-api-payout/src/index.css
================================================
@tailwind base;
@tailwind components;
@tailwind utilities;
================================================
FILE: submissions/chiconnect-bank-api-payout/src/main.jsx
================================================
import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App'
import './index.css'
ReactDOM.createRoot(document.getElementById('root')).render(
)
================================================
FILE: submissions/chiconnect-bank-api-payout/src/service/fetchApi.js
================================================
export const API_KEY = `${import.meta.env.VITE_API_KEY}`
export const getBanks = async () => {
const response = await fetch('https://api.chimoney.io/v0.2/info/country-banks?countryCode=NG', {
method: 'GET',
headers: {
'Content-Type': 'application/json',
'X-API-KEY': API_KEY
}
})
const data = await response.json()
return data
}
================================================
FILE: submissions/chiconnect-bank-api-payout/tailwind.config.cjs
================================================
/** @type {import('tailwindcss').Config} */
module.exports = {
content: [
'./index.html',
'./src/**/*.{js,ts,jsx,tsx}',
],
theme: {
extend: {},
},
plugins: [],
}
================================================
FILE: submissions/chiconnect-bank-api-payout/vite.config.js
================================================
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [react()]
})
================================================
FILE: submissions/chiconnect-giftcard-payout/.gitignore
================================================
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*
node_modules
dist
dist-ssr
*.local
# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
================================================
FILE: submissions/chiconnect-giftcard-payout/README.md
================================================
# Chiconnect giftcard payout
A mini project to demonstrate integration of Chiconnect giftcard payout using React framework.
## Setup
- `git clone `
- `cd chimoney-api-community-projects/submissions/chiconnect-giftcard-payout`
- `npm install`
- create a file in root directory with `.env` as the name and add the API key in this format VITE_API_KEY='api key'`
- `npm run dev`
## Commit style guidelines
A commit message should easily convey what it contains so this guidelines shows a commit should be for this project.
The commit message should be in this format `type: subject` where `type` can be any one of these:
- `feat: a new feature`
- `fix: a bug fix`
- `docs: changes to documentation`
- `style: formatting, missing semi colons, etc; no code change`
- `refactor: refactoring production code`
- `test: adding tests, refactoring test; no production code change`
- `chore: updating build tasks, package manager configs, etc; no production code change`
and the `subject` should be no greater than 50 characters, should begin with an uppercase and should use imperative tone. E.g: 'change'; not 'changed' or 'changes'
================================================
FILE: submissions/chiconnect-giftcard-payout/index.html
================================================
Giftcard Payout
================================================
FILE: submissions/chiconnect-giftcard-payout/package.json
================================================
{
"name": "chiconnect-giftcard-payout",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "vite build",
"preview": "vite preview"
},
"dependencies": {
"react": "^18.2.0",
"react-dom": "^18.2.0"
},
"devDependencies": {
"@types/react": "^18.0.17",
"@types/react-dom": "^18.0.6",
"@vitejs/plugin-react": "^2.1.0",
"autoprefixer": "^10.4.12",
"postcss": "^8.4.17",
"tailwindcss": "^3.1.8",
"vite": "^3.1.0",
"vite-plugin-environment": "^1.1.3"
}
}
================================================
FILE: submissions/chiconnect-giftcard-payout/postcss.config.cjs
================================================
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
}
================================================
FILE: submissions/chiconnect-giftcard-payout/src/App.jsx
================================================
import { useState } from 'react'
import chimoneyLogo from './assets/chimoney-logo.svg'
import Giftcards from './components/Giftcards'
function App() {
const [error, setError] = useState('')
const [info, setInfo] = useState('')
const [loading, setLoading] = useState(false)
const API_KEY = `${process.env.API_KEY}`
const [paymentData, setPaymentData] = useState({
'email': '',
'productId': '',
'name': '',
'countryCode': 'US',
'amount': '',
'max': null,
'min': null,
'denominations': null
})
const setProduct = (id, name, countryCode, max, min, denominations) => {
setPaymentData(prevData => ({
...prevData,
'productId': id,
'name': name,
'countryCode': countryCode,
'max': max,
'min': min,
'denominations': denominations
}))
denominations && setPaymentData(prevData => ({...prevData, 'amount': denominations[0]}))
}
const handleFormChange = (event) => {
const { name, value } = event.target
setPaymentData(prevData => ({
...prevData,
[name]: value
}))
}
const sendGiftcard = async () => {
const baseUrl = 'https://api.chimoney.io/v0.2/'
fetch(`${baseUrl}/payouts/initiate-chimoney`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-API-KEY': API_KEY
},
body: JSON.stringify({
chimoneys: [
{
email: paymentData.email,
valueInUSD: Number(paymentData.amount),
redeemData: {
productId: Number(paymentData.productId),
countryCode: paymentData.countryCode
}
}
]
})
}).then(response => response.json())
.then(result => {
setLoading(false)
if (result.status === 'error') {
setError(result.error)
setInfo('')
} else {
const paymentLink = result.data.paymentLink
window.open(paymentLink) // redirect to chimoney redeem payment page
}
})
.catch(err => console.error(err.message))
}
const handleClick = () => {
if (paymentData.email.length === 0) {
setError('Email cannot be empty')
return
} else {
const emailPattern = new RegExp(/^[a-zA-Z0-9]+@[a-z]+\.[a-z]{2,3}$/)
const isMatch = paymentData.email.match(emailPattern)
if (!isMatch) {
setError('Invalid email')
return
}
}
if (paymentData.denominations === null && paymentData.max === null && paymentData.min === null) {
setError('Select a giftcard')
return
}
if (paymentData.amount.length === 0) {
setError('Amount cannot be empty')
return
} else if (paymentData.denominations === null) {
const amount = paymentData.amount
if (amount < paymentData.min) {
setError(`Amount cannot be below $${paymentData.min}`)
return
} else if (amount > paymentData.max) {
setError(`Amount cannot be above $${paymentData.max}`)
return
}
}
if (paymentData.countryCode.length === 0) {
setError('Country code cannot be empty')
return
}
if (paymentData.productId.length === 0) {
setError('Select a giftcard above')
return
}
setLoading(true)
setError('')
setInfo('Please wait...')
sendGiftcard()
}
return (
)
}
export default Giftcards
================================================
FILE: submissions/chiconnect-giftcard-payout/src/index.css
================================================
@tailwind base;
@tailwind components;
@tailwind utilities;
================================================
FILE: submissions/chiconnect-giftcard-payout/src/main.jsx
================================================
import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App'
import './index.css'
ReactDOM.createRoot(document.getElementById('root')).render(
)
================================================
FILE: submissions/chiconnect-giftcard-payout/src/service/fetchApi.js
================================================
export const API_KEY = `${import.meta.env.VITE_API_KEY}`
export const getGiftcards = async (countryCode) => {
const response = await fetch(`https://api.chimoney.io/v0.2/info/assets?countryCode=${countryCode}`, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
'X-API-KEY': API_KEY
}
})
return await response.json()
}
================================================
FILE: submissions/chiconnect-giftcard-payout/tailwind.config.cjs
================================================
/** @type {import('tailwindcss').Config} */
module.exports = {
content: [
'./index.html',
'./src/**/*.{js,ts,jsx,tsx}',
],
theme: {
extend: {
animation: {
slideup: 'slideup .5s ease-in'
},
keyframes: {
slideup: {
from: { opacity: 0, transform: 'translateY(25%)' },
to: { opacity: 1, transform: 'none' },
},
}
},
},
plugins: [],
}
================================================
FILE: submissions/chiconnect-giftcard-payout/vite.config.js
================================================
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import EnvironmentPlugin from 'vite-plugin-environment'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [
react(),
EnvironmentPlugin(['API_KEY'])
]
})
================================================
FILE: submissions/chiconnect-laravel-web-app/.editorconfig
================================================
root = true
[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
indent_style = space
indent_size = 4
trim_trailing_whitespace = true
[*.md]
trim_trailing_whitespace = false
[*.{yml,yaml}]
indent_size = 2
[docker-compose.yml]
indent_size = 4
================================================
FILE: submissions/chiconnect-laravel-web-app/.gitattributes
================================================
* text=auto
*.blade.php diff=html
*.css diff=css
*.html diff=html
*.md diff=markdown
*.php diff=php
/.github export-ignore
CHANGELOG.md export-ignore
.styleci.yml export-ignore
================================================
FILE: submissions/chiconnect-laravel-web-app/.gitignore
================================================
/node_modules
/public/build
/public/hot
/public/storage
/storage/*.key
/vendor
.env
.env.backup
.phpunit.result.cache
Homestead.json
Homestead.yaml
auth.json
npm-debug.log
yarn-error.log
/.idea
/.vscode
================================================
FILE: submissions/chiconnect-laravel-web-app/Laravel SDK Installation and Setup Guide.md
================================================
# Chimoney Laravel SDK Installation and Setup Guide
## Installation
Installation Instructions:
### Prerequisites:
- **PHP**: Ensure your Laravel project is using PHP version 7.4 or higher.
- **Composer**: Make sure Composer is installed. You can verify by running `composer -v` in your terminal.
- **Laravel Framework**: Your project should be using Laravel version 8.x or higher.
### Step 1: Install via Composer
In your Laravel project directory, run the following command to install the Chimoney SDK:
`composer require chimoney/laravel-sdk`
### Step 2: Publish Configuration
After installing the package, you need to publish the configuration file. This will allow you to customize the SDK settings (such as API keys) for your application:
Publish the package configuration file:
`php artisan vendor:publish --provider="Chimoney\Laravel\ChimoneyServiceProvider"`
This command creates a `chimoney.php` `config` file in your config directory.
### Update Environment Variables
You need to add your Chimoney API keys to the `.env `file of your Laravel project. Here's how you should configure it:
```
CHIMONEY_API_KEY=your-chimoney-api-key
CHIMONEY_BASE_URL=https://api.chimoney.io
```
> Replace `your-chimoney-api-key` with the actual API key provided by Chimoney, and ensure the base URL is correct for the environment you're working with.
## Configuration
**Configuration File**
- The configuration file will be published at `config/chimoney.php.`
- You can modify the default settings here:
```
return [
'api_key' => env('CHIMONEY_API_KEY'),
'environment' => env('CHIMONEY_ENVIRONMENT', 'sandbox'),
'timeout' => 30,
'verify_ssl' => true,
];
```
## Usage Guide
### Authentication
Once the SDK is installed and configured, you can start making requests to the Chimoney API. First, you need to authenticate your API requests using the API key set in your `.env`file.
### Sending Requests
Here’s a simple example to make a request:
1. Initialize the Chimoney Client
In your Laravel controller or service class, you can initialize the Chimoney client like this:
```
use Chimoney\Laravel\Chimoney;
class ChimoneyController extends Controller
{
protected $chimoney;
public function __construct(Chimoney $chimoney)
{
$this->chimoney = $chimoney;
}
public function getBalance()
{
// Example: Get account balance
$response = $this->chimoney->getBalance();
if ($response->successful()) {
return response()->json($response->json());
} else {
return response()->json(['error' => 'Failed to retrieve balance.'], 500);
}
}
}
```
2. Example of Sending a Payment Request
Example of Sending a Payment Request:
```
public function sendPayment()
{
$paymentData = [
'amount' => 100,
'currency' => 'USD',
'recipient' => 'recipient@example.com',
];
$response = $this->chimoney->sendPayment($paymentData);
if ($response->successful()) {
return response()->json($response->json());
} else {
return response()->json(['error' => 'Payment failed.'], 500);
}
}
```
### Handling Responses
The SDK returns a standard Laravel `Response` object, so you can handle responses as you normally would in Laravel:
```
if ($response->successful()) {
// Process successful response
} else {
// Handle error
$error = $response->json('message');
}
```
## Configuration Details
You can manage the API keys and other configurations in your `.env` file. Below are the configurations that the Chimoney Laravel SDK expects:
- `.env` File Configuration:
```
CHIMONEY_API_KEY=your-chimoney-api-key
CHIMONEY_BASE_URL=https://api.chimoney.io
```
- **Customizing Configurations**
If you need to change the API base URL or other settings, you can update them in the `config/chimoney.php` file:
```
return [
'api_key' => env('CHIMONEY_API_KEY'),
'base_url' => env('CHIMONEY_BASE_URL', 'https://api.chimoney.io'),
];
```
## Testing Instructions
To ensure that the Chimoney SDK is installed and configured correctly, follow these steps:
1. Run Basic Tests
After installation, ensure the SDK is functioning by testing the connection to the API. Add a test route in your `routes/web.php` file:
```
use App\Http\Controllers\ChimoneyController;
Route::get('/test-chimoney', [ChimoneyController::class, 'getBalance']);
```
> Visit http://your-app-url/test-chimoney. If the SDK is working, it should return your Chimoney account balance or other test data.
2. Unit Tests
You can write unit tests to check specific SDK functionalities. Here’s an example of how to test the `getBalance` method:
```
public function testChimoneyBalance()
{
$response = $this->chimoney->getBalance();
$this->assertTrue($response->successful());
}
```
3. Artisan Command for Testing
If you want to run tests through the CLI, you can use `php artisan test` to run your Laravel test suite and verify that everything is working as expected.
### Sandbox Testing
1. Create a sandbox account at Chimoney Developer Portal.
2. Use the sandbox API key in your `.env file`.
3. Test transactions will not result in actual money movement.
## Troubleshooting
## Common Issues and Solutions
- **API Key Issues**
```
// Verify your API key is properly set
echo config('chimoney.api_key');
```
- **SSL Certificate Issues**
If you encounter SSL verification issues, you can disable SSL verification in the config file (not recommended for production):
```
// config/chimoney.php
return [
// ...
'verify_ssl' => false,
];
```
- **Request Timeout**
Adjust the timeout in the configuration if requests are timing out:
```
// config/chimoney.php
return [
// ...
'timeout' => 60, // Increase timeout to 60 seconds
];
```
## Error Handling
The SDK throws `ChimoneyException` for API-related errors. Always wrap API calls in try-catch blocks:
```
try {
$result = Chimoney::someMethod();
} catch (\Chimoney\Laravel\Exceptions\ChimoneyException $e) {
// Log the error
\Log::error('Chimoney API Error: ' . $e->getMessage());
// Get error details
$statusCode = $e->getCode();
$errorMessage = $e->getMessage();
$errorResponse = $e->getResponse();
}
```
By following these steps, you should be able to successfully install, configure, troubleshoot and use the Chimoney Laravel SDK within your Laravel project. For more advanced usage and further API details, refer to the official Chimoney [API documentation](https://chimoney.readme.io/reference/introduction).
*For any additional support, please refer to the official Chimoney documentation or create an issue in the GitHub repository.*
================================================
FILE: submissions/chiconnect-laravel-web-app/Procfile
================================================
web: vendor/bin/heroku-php-apache2 public/
================================================
FILE: submissions/chiconnect-laravel-web-app/README.md
================================================
## About Laravel
Laravel is a web application framework with expressive, elegant syntax. We believe development must be an enjoyable and creative experience to be truly fulfilling. Laravel takes the pain out of development by easing common tasks used in many web projects, such as:
- [Simple, fast routing engine](https://laravel.com/docs/routing).
- [Powerful dependency injection container](https://laravel.com/docs/container).
- Multiple back-ends for [session](https://laravel.com/docs/session) and [cache](https://laravel.com/docs/cache) storage.
- Expressive, intuitive [database ORM](https://laravel.com/docs/eloquent).
- Database agnostic [schema migrations](https://laravel.com/docs/migrations).
- [Robust background job processing](https://laravel.com/docs/queues).
- [Real-time event broadcasting](https://laravel.com/docs/broadcasting).
Laravel is accessible, powerful, and provides tools required for large, robust applications.
## Learning Laravel
Laravel has the most extensive and thorough [documentation](https://laravel.com/docs) and video tutorial library of all modern web application frameworks, making it a breeze to get started with the framework.
You may also try the [Laravel Bootcamp](https://bootcamp.laravel.com), where you will be guided through building a modern Laravel application from scratch.
If you don't feel like reading, [Laracasts](https://laracasts.com) can help. Laracasts contains over 2000 video tutorials on a range of topics including Laravel, modern PHP, unit testing, and JavaScript. Boost your skills by digging into our comprehensive video library.
## Laravel Sponsors
We would like to extend our thanks to the following sponsors for funding Laravel development. If you are interested in becoming a sponsor, please visit the Laravel [Patreon page](https://patreon.com/taylorotwell).
### Premium Partners
- **[Vehikl](https://vehikl.com/)**
- **[Tighten Co.](https://tighten.co)**
- **[Kirschbaum Development Group](https://kirschbaumdevelopment.com)**
- **[64 Robots](https://64robots.com)**
- **[Cubet Techno Labs](https://cubettech.com)**
- **[Cyber-Duck](https://cyber-duck.co.uk)**
- **[Many](https://www.many.co.uk)**
- **[Webdock, Fast VPS Hosting](https://www.webdock.io/en)**
- **[DevSquad](https://devsquad.com)**
- **[Curotec](https://www.curotec.com/services/technologies/laravel/)**
- **[OP.GG](https://op.gg)**
- **[WebReinvent](https://webreinvent.com/?utm_source=laravel&utm_medium=github&utm_campaign=patreon-sponsors)**
- **[Lendio](https://lendio.com)**
## Contributing
Thank you for considering contributing to the Laravel framework! The contribution guide can be found in the [Laravel documentation](https://laravel.com/docs/contributions).
## Code of Conduct
In order to ensure that the Laravel community is welcoming to all, please review and abide by the [Code of Conduct](https://laravel.com/docs/contributions#code-of-conduct).
## Security Vulnerabilities
If you discover a security vulnerability within Laravel, please send an e-mail to Taylor Otwell via [taylor@laravel.com](mailto:taylor@laravel.com). All security vulnerabilities will be promptly addressed.
## License
The Laravel framework is open-sourced software licensed under the [MIT license](https://opensource.org/licenses/MIT).
================================================
FILE: submissions/chiconnect-laravel-web-app/app/Console/Kernel.php
================================================
command('inspire')->hourly();
}
/**
* Register the commands for the application.
*
* @return void
*/
protected function commands()
{
$this->load(__DIR__.'/Commands');
require base_path('routes/console.php');
}
}
================================================
FILE: submissions/chiconnect-laravel-web-app/app/Exceptions/Handler.php
================================================
, \Psr\Log\LogLevel::*>
*/
protected $levels = [
//
];
/**
* A list of the exception types that are not reported.
*
* @var array>
*/
protected $dontReport = [
//
];
/**
* A list of the inputs that are never flashed to the session on validation exceptions.
*
* @var array
*/
protected $dontFlash = [
'current_password',
'password',
'password_confirmation',
];
/**
* Register the exception handling callbacks for the application.
*
* @return void
*/
public function register()
{
$this->reportable(function (Throwable $e) {
//
});
}
}
================================================
FILE: submissions/chiconnect-laravel-web-app/app/Http/Controllers/AccountController.php
================================================
$user
]);
}
public function topUp(Request $request)
{
$request->validate([
'amount' => ['required', 'numeric'],
]);
$top_up_user = Account::transfer('', $request->receiver, $request->amount);
if ($top_up_user) {
$data = $top_up_user->data;
Transaction::create([
'receiver' => $data->receiver,
'sender' => $data->sender,
'wallet' => $data->wallet,
'tnxID' => $data->tnxID,
'amount' => $data->amount,
]);
return redirect()->back()->with('status', 'Transaction successful');
}
return redirect()->back()->with('error', 'Oops, something went wrong')->withInput($request->input());
}
public function createTransfer()
{
$user = auth()->user();
return view('transfer.create', [
'balance' => Wallet::fetchBalance($user->chi_wallet_id, $user->sub_account_id)
]);
}
public function processTransfer(Request $request)
{
$request->validate([
'username' => ['required', 'string', 'exists:users'],
'amount' => ['required', 'numeric'],
]);
$receiver = User::where('username', $request->username)->first();
$send_money = Account::transfer(auth()->user()->sub_account_id, $receiver->sub_account_id, $request->amount);
if ($send_money) {
$data = $send_money->data;
Transaction::create([
'receiver' => $data->receiver,
'sender' => $data->sender,
'wallet' => $data->wallet,
'tnxID' => $data->tnxID,
'amount' => $data->amount,
]);
return redirect()->back()->with('status', 'Transaction successful');
}
return redirect()->back()->with('error', 'Oops, something went wrong')->withInput($request->input());
}
public function transferHistory()
{
$user = auth()->user();
$transfers = Transaction::query()
->where('wallet', 'chi')
->where(function ($query) use ($user) {
$query->where('receiver', $user->sub_account_id)
->orWhere('sender', $user->sub_account_id);
})
->with(['from', 'to'])
->latest()
->paginate(10);
return view('transfer.history', [
'transfers' => $transfers
]);
}
}
================================================
FILE: submissions/chiconnect-laravel-web-app/app/Http/Controllers/Auth/AuthenticatedSessionController.php
================================================
authenticate();
$request->session()->regenerate();
return redirect()->intended(RouteServiceProvider::HOME);
}
/**
* Destroy an authenticated session.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\RedirectResponse
*/
public function destroy(Request $request)
{
Auth::guard('web')->logout();
$request->session()->invalidate();
$request->session()->regenerateToken();
return redirect('/');
}
}
================================================
FILE: submissions/chiconnect-laravel-web-app/app/Http/Controllers/Auth/ConfirmablePasswordController.php
================================================
validate([
'email' => $request->user()->email,
'password' => $request->password,
])) {
throw ValidationException::withMessages([
'password' => __('auth.password'),
]);
}
$request->session()->put('auth.password_confirmed_at', time());
return redirect()->intended(RouteServiceProvider::HOME);
}
}
================================================
FILE: submissions/chiconnect-laravel-web-app/app/Http/Controllers/Auth/EmailVerificationNotificationController.php
================================================
user()->hasVerifiedEmail()) {
return redirect()->intended(RouteServiceProvider::HOME);
}
$request->user()->sendEmailVerificationNotification();
return back()->with('status', 'verification-link-sent');
}
}
================================================
FILE: submissions/chiconnect-laravel-web-app/app/Http/Controllers/Auth/EmailVerificationPromptController.php
================================================
user()->hasVerifiedEmail()
? redirect()->intended(RouteServiceProvider::HOME)
: view('auth.verify-email');
}
}
================================================
FILE: submissions/chiconnect-laravel-web-app/app/Http/Controllers/Auth/NewPasswordController.php
================================================
$request]);
}
/**
* Handle an incoming new password request.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\RedirectResponse
*
* @throws \Illuminate\Validation\ValidationException
*/
public function store(Request $request)
{
$request->validate([
'token' => ['required'],
'email' => ['required', 'email'],
'password' => ['required', 'confirmed', Rules\Password::defaults()],
]);
// Here we will attempt to reset the user's password. If it is successful we
// will update the password on an actual user model and persist it to the
// database. Otherwise we will parse the error and return the response.
$status = Password::reset(
$request->only('email', 'password', 'password_confirmation', 'token'),
function ($user) use ($request) {
$user->forceFill([
'password' => Hash::make($request->password),
'remember_token' => Str::random(60),
])->save();
event(new PasswordReset($user));
}
);
// If the password was successfully reset, we will redirect the user back to
// the application's home authenticated view. If there is an error we can
// redirect them back to where they came from with their error message.
return $status == Password::PASSWORD_RESET
? redirect()->route('login')->with('status', __($status))
: back()->withInput($request->only('email'))
->withErrors(['email' => __($status)]);
}
}
================================================
FILE: submissions/chiconnect-laravel-web-app/app/Http/Controllers/Auth/PasswordResetLinkController.php
================================================
validate([
'email' => ['required', 'email'],
]);
// We will send the password reset link to this user. Once we have attempted
// to send the link, we will examine the response then see the message we
// need to show to the user. Finally, we'll send out a proper response.
$status = Password::sendResetLink(
$request->only('email')
);
return $status == Password::RESET_LINK_SENT
? back()->with('status', __($status))
: back()->withInput($request->only('email'))
->withErrors(['email' => __($status)]);
}
}
================================================
FILE: submissions/chiconnect-laravel-web-app/app/Http/Controllers/Auth/RegisteredUserController.php
================================================
validate([
'name' => ['required', 'string', 'max:255', 'min:2'],
'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
'password' => ['required', 'confirmed', Rules\Password::defaults()],
'username' => ['required', 'string', 'max:255', 'min:2', 'unique:users']
]);;
$user = User::create([
'name' => $request->name,
'email' => $request->email,
'password' => Hash::make($request->password),
'username' => $request->username,
'uuid' => Str::uuid(),
]);
if ($sub_account_id = SubAccount::create($request->name, $request->email)) {
$user->update([
'sub_account_id' => $sub_account_id
]);
}
event(new Registered($user));
Auth::login($user);
return redirect(RouteServiceProvider::HOME);
}
}
================================================
FILE: submissions/chiconnect-laravel-web-app/app/Http/Controllers/Auth/VerifyEmailController.php
================================================
user()->hasVerifiedEmail()) {
return redirect()->intended(RouteServiceProvider::HOME.'?verified=1');
}
if ($request->user()->markEmailAsVerified()) {
event(new Verified($request->user()));
}
return redirect()->intended(RouteServiceProvider::HOME.'?verified=1');
}
}
================================================
FILE: submissions/chiconnect-laravel-web-app/app/Http/Controllers/Controller.php
================================================
Payout::where('issuer', auth()->user()->sub_account_id)->latest()->paginate(10)
]);
}
public function createAirtime()
{
$user = auth()->user();
return view('payout.airtime', [
'balance' => Wallet::fetchBalance($user->chi_wallet_id, $user->sub_account_id)
]);
}
public function createBank()
{
$user = auth()->user();
return view('payout.bank', [
'balance' => Wallet::fetchBalance($user->chi_wallet_id, $user->sub_account_id)
]);
}
}
================================================
FILE: submissions/chiconnect-laravel-web-app/app/Http/Controllers/ProfileController.php
================================================
User::Latest()->paginate(10)
]);
}
public function show(User $user)
{
return view('profile.show', [
'user' => $user,
'wallets' => Wallet::fetchAll($user->sub_account_id),
'wallet_type' => [
'airtime' => 'Airtime balance',
'chi' => 'Flexible balance',
'momo' => 'Mobile money'
]
]);
}
public function dashboard()
{
$user = auth()->user();
$balance = null;
if (is_null($user->chi_wallet_id)) {
$wallet = Wallet::fetchType('chi', $user->sub_account_id);
User::find($user->id)->update([
'chi_wallet_id' => $wallet->id
]);
$balance = $wallet->balance;
}
return view('dashboard', [
'balance' => $wallet->balance ?? Wallet::fetchBalance($user->chi_wallet_id, $user->sub_account_id)
]);
}
}
================================================
FILE: submissions/chiconnect-laravel-web-app/app/Http/Kernel.php
================================================
*/
protected $middleware = [
// \App\Http\Middleware\TrustHosts::class,
\App\Http\Middleware\TrustProxies::class,
\Illuminate\Http\Middleware\HandleCors::class,
\App\Http\Middleware\PreventRequestsDuringMaintenance::class,
\Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
\App\Http\Middleware\TrimStrings::class,
\Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
];
/**
* The application's route middleware groups.
*
* @var array>
*/
protected $middlewareGroups = [
'web' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
'api' => [
// \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
'throttle:api',
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
];
/**
* The application's route middleware.
*
* These middleware may be assigned to groups or used individually.
*
* @var array
*/
protected $routeMiddleware = [
'auth' => \App\Http\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'auth.session' => \Illuminate\Session\Middleware\AuthenticateSession::class,
'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
'can' => \Illuminate\Auth\Middleware\Authorize::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'password.confirm' => \Illuminate\Auth\Middleware\RequirePassword::class,
'signed' => \App\Http\Middleware\ValidateSignature::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
];
}
================================================
FILE: submissions/chiconnect-laravel-web-app/app/Http/Livewire/Auth/RegisterUser.php
================================================
username = old('username') ?? '';
}
public function updatedUsername()
{
$this->validate([
'username' => ['unique:users']
]);
}
public function render()
{
return view('livewire.auth.register-user');
}
}
================================================
FILE: submissions/chiconnect-laravel-web-app/app/Http/Livewire/ProcessAirtime.php
================================================
countries = Info::AirtimeCountries();
}
public function submit()
{
$this->validate([
'phone' => ['required'],
'amount' => ['required', 'min:1', 'max:' . $this->balance, 'numeric'],
'country' => ['required']
]);
$process_airtime = Payout::Airtime(auth()->user()->sub_account_id, $this->country, $this->phone, $this->amount);
if ($process_airtime && $data = $process_airtime[0]) {
ModelsPayout::create([
'issuer' => $data->issuer,
'chiRef' => $data->chiRef,
'type' => $data->type,
'amount' => $data->valueInUSD,
'recipient' => $data->phoneNumber
]);
$this->balance = Wallet::fetchBalance(auth()->user()->chi_wallet_id, auth()->user()->sub_account_id) ?? 0;
$this->reset(['country', 'amount', 'phone']);
session()->flash('status', 'Payout was successful');
} else {
session()->flash('error', 'Oops, something went wrong');
}
}
public function render()
{
return view('livewire.process-airtime');
}
}
================================================
FILE: submissions/chiconnect-laravel-web-app/app/Http/Livewire/ProcessBank.php
================================================
countries = getCountryCodes();
}
public function updatedCountry()
{
$this->resetErrorBag('country');
$this->reset(['country_banks', 'bank', 'account_holder']);
$banks = collect(Info::CountryBanks($this->country));
if ($banks->has('data')) {
return $this->addError('country', 'This country is not supported');
}
$this->country_banks = $banks;
}
public function updatedBank()
{
$this->reset(['amount', 'account', 'account_holder']);
}
public function updatedAccount()
{
$this->reset('account_holder');
$this->confirmAccount();
}
public function confirmAccount()
{
$account_info = Info::VerifyAccountNumber($this->country, $this->bank, $this->account);
if ($account_info && $account_info->status == 'success') {
$this->account_holder = $account_info->data[0]->account_name;
return $this->resetErrorBag('account');
}
return $this->addError('account', 'Invalid account number');
}
public function submit()
{
$this->validate([
'country' => ['required'],
'amount' => ['required', 'min:1', 'max:' . $this->balance, 'numeric'],
'account' => ['required'],
'bank' => ['required']
]);
$this->confirmAccount();
// Generate transaction reference
$tnxRef = TransactionReference::create([
'uuid' => Str::orderedUuid()
]);
$process_bank = Payout::Bank(auth()->user()->sub_account_id, getCountryCodes()[$this->country], $this->bank, $this->account, $this->amount, $tnxRef->uuid);
if ($process_bank && $data = $process_bank[0]) {
ModelsPayout::create([
'issuer' => $data->issuer,
'chiRef' => $data->chiRef,
'type' => $data->type,
'amount' => $data->valueInUSD,
'recipient' => $data->account_number
]);
$tnxRef->chiRef = $data->chiRef;
$tnxRef->save();
$this->balance = Wallet::fetchBalance(auth()->user()->chi_wallet_id, auth()->user()->sub_account_id) ?? 0;
$this->reset(['country_banks', 'bank', 'account_holder', 'amount']);
session()->flash('status', 'Bank payout was successful');
} else {
session()->flash('error', 'Oops, something went wrong');
}
}
public function render()
{
return view('livewire.process-bank');
}
}
================================================
FILE: submissions/chiconnect-laravel-web-app/app/Http/Livewire/Username.php
================================================
search = $this->username = old('username') ?? '';
}
public function selectUser($username)
{
$this->username = $username;
$this->search = $username;
$this->users = [];
}
public function updatedSearch()
{
unset($this->username);
$this->users = User::query()
->where('username', 'LIKE', '%' . $this->search . '%')
->where('id', '!=', auth()->id())
->orderBy('username', 'asc')
->get();
}
public function render()
{
return view('livewire.username');
}
}
================================================
FILE: submissions/chiconnect-laravel-web-app/app/Http/Middleware/Authenticate.php
================================================
expectsJson()) {
return route('login');
}
}
}
================================================
FILE: submissions/chiconnect-laravel-web-app/app/Http/Middleware/EncryptCookies.php
================================================
*/
protected $except = [
//
];
}
================================================
FILE: submissions/chiconnect-laravel-web-app/app/Http/Middleware/PreventRequestsDuringMaintenance.php
================================================
*/
protected $except = [
//
];
}
================================================
FILE: submissions/chiconnect-laravel-web-app/app/Http/Middleware/RedirectIfAuthenticated.php
================================================
check()) {
return redirect(RouteServiceProvider::HOME);
}
}
return $next($request);
}
}
================================================
FILE: submissions/chiconnect-laravel-web-app/app/Http/Middleware/TrimStrings.php
================================================
*/
protected $except = [
'current_password',
'password',
'password_confirmation',
];
}
================================================
FILE: submissions/chiconnect-laravel-web-app/app/Http/Middleware/TrustHosts.php
================================================
*/
public function hosts()
{
return [
$this->allSubdomainsOfApplicationUrl(),
];
}
}
================================================
FILE: submissions/chiconnect-laravel-web-app/app/Http/Middleware/TrustProxies.php
================================================
|string|null
*/
protected $proxies;
/**
* The headers that should be used to detect proxies.
*
* @var int
*/
protected $headers =
Request::HEADER_X_FORWARDED_FOR |
Request::HEADER_X_FORWARDED_HOST |
Request::HEADER_X_FORWARDED_PORT |
Request::HEADER_X_FORWARDED_PROTO |
Request::HEADER_X_FORWARDED_AWS_ELB;
}
================================================
FILE: submissions/chiconnect-laravel-web-app/app/Http/Middleware/ValidateSignature.php
================================================
*/
protected $except = [
// 'fbclid',
// 'utm_campaign',
// 'utm_content',
// 'utm_medium',
// 'utm_source',
// 'utm_term',
];
}
================================================
FILE: submissions/chiconnect-laravel-web-app/app/Http/Middleware/VerifyCsrfToken.php
================================================
*/
protected $except = [
//
];
}
================================================
FILE: submissions/chiconnect-laravel-web-app/app/Http/Requests/Auth/LoginRequest.php
================================================
['required', 'string', 'email'],
'password' => ['required', 'string'],
];
}
/**
* Attempt to authenticate the request's credentials.
*
* @return void
*
* @throws \Illuminate\Validation\ValidationException
*/
public function authenticate()
{
$this->ensureIsNotRateLimited();
if (! Auth::attempt($this->only('email', 'password'), $this->boolean('remember'))) {
RateLimiter::hit($this->throttleKey());
throw ValidationException::withMessages([
'email' => trans('auth.failed'),
]);
}
RateLimiter::clear($this->throttleKey());
}
/**
* Ensure the login request is not rate limited.
*
* @return void
*
* @throws \Illuminate\Validation\ValidationException
*/
public function ensureIsNotRateLimited()
{
if (! RateLimiter::tooManyAttempts($this->throttleKey(), 5)) {
return;
}
event(new Lockout($this));
$seconds = RateLimiter::availableIn($this->throttleKey());
throw ValidationException::withMessages([
'email' => trans('auth.throttle', [
'seconds' => $seconds,
'minutes' => ceil($seconds / 60),
]),
]);
}
/**
* Get the rate limiting throttle key for the request.
*
* @return string
*/
public function throttleKey()
{
return Str::transliterate(Str::lower($this->input('email')).'|'.$this->ip());
}
}
================================================
FILE: submissions/chiconnect-laravel-web-app/app/Models/Payout.php
================================================
belongsTo(User::class, 'receiver', 'sub_account_id');
}
public function from()
{
return $this->belongsTo(User::class, 'sender', 'sub_account_id');
}
}
================================================
FILE: submissions/chiconnect-laravel-web-app/app/Models/TransactionReference.php
================================================
*/
protected $fillable = [
'name',
'email',
'password',
'uuid',
'sub_account_id',
'username',
'chi_wallet_id'
];
/**
* The attributes that should be hidden for serialization.
*
* @var array
*/
protected $hidden = [
'password',
'remember_token',
];
/**
* The attributes that should be cast.
*
* @var array
*/
protected $casts = [
'email_verified_at' => 'datetime',
];
}
================================================
FILE: submissions/chiconnect-laravel-web-app/app/Providers/AppServiceProvider.php
================================================
*/
protected $policies = [
// 'App\Models\Model' => 'App\Policies\ModelPolicy',
];
/**
* Register any authentication / authorization services.
*
* @return void
*/
public function boot()
{
$this->registerPolicies();
//
}
}
================================================
FILE: submissions/chiconnect-laravel-web-app/app/Providers/BroadcastServiceProvider.php
================================================
>
*/
protected $listen = [
Registered::class => [
SendEmailVerificationNotification::class,
],
];
/**
* Register any events for your application.
*
* @return void
*/
public function boot()
{
//
}
/**
* Determine if events and listeners should be automatically discovered.
*
* @return bool
*/
public function shouldDiscoverEvents()
{
return false;
}
}
================================================
FILE: submissions/chiconnect-laravel-web-app/app/Providers/RouteServiceProvider.php
================================================
configureRateLimiting();
$this->routes(function () {
Route::middleware('api')
->prefix('api')
->group(base_path('routes/api.php'));
Route::middleware('web')
->group(base_path('routes/web.php'));
});
}
/**
* Configure the rate limiters for the application.
*
* @return void
*/
protected function configureRateLimiting()
{
RateLimiter::for('api', function (Request $request) {
return Limit::perMinute(60)->by($request->user()?->id ?: $request->ip());
});
}
}
================================================
FILE: submissions/chiconnect-laravel-web-app/app/Support/Chiconnect/Account.php
================================================
$to,
'amount' => $amount,
'wallet' => $wallet
];
if ($from) {
$payload['subAccount'] = $from;
}
$response = Http::withHeaders([
'X-API-KEY' => config('chimoney.api_key'),
'accept' => 'application/json',
'content-type' => 'application/json',
])->post('https://api.chimoney.io/v0.2/accounts/transfer', $payload);
if ($response->status() == 200) {
return json_decode($response)->data;
}
return false;
}
public static function getWallets(string $sub_account)
{
$payload = ['id' => $sub_account];
$response = Http::withHeaders([
'X-API-KEY' => config('chimoney.api_key'),
'accept' => 'application/json',
'content-type' => 'application/json',
])->get('https://api.chimoney.io/v0.2/sub-account/get', $payload);
if ($response->status() == 200) {
return json_decode($response)->data->wallets;
}
return false;
}
public static function getWalletByType(string $type, string $sub_account)
{
if (!in_array($type, ['chi', 'airtime', 'momo'])) {
return false;
}
return collect(self::getWallets($sub_account))->where('type', $type)->first() ?? false;
}
}
================================================
FILE: submissions/chiconnect-laravel-web-app/app/Support/Chiconnect/Info.php
================================================
config('chimoney.api_key'),
'accept' => 'application/json',
'content-type' => 'application/json',
])->get('https://api.chimoney.io/v0.2/info/airtime-countries');
if ($response->status() == 200) {
return json_decode($response)->data;
}
return [];
}
public static function CountryBanks(string $country_code)
{
$response = Http::withHeaders([
'X-API-KEY' => config('chimoney.api_key'),
'accept' => 'application/json',
'content-type' => 'application/json',
])->get('https://api.chimoney.io/v0.2/info/country-banks', [
'countryCode' => $country_code
]);
if ($response->status() == 200) {
return json_decode($response)->data;
}
return [];
}
public static function VerifyAccountNumber(string $country_code, string $bank_code, string $account)
{
$response = Http::withHeaders([
'X-API-KEY' => config('chimoney.api_key'),
'accept' => 'application/json',
'content-type' => 'application/json',
])->post('https://api.chimoney.io/v0.2/info/verify-bank-account-number', [
'verifyAccountNumbers' => [
[
'countryCode' => $country_code,
'account_bank' => $bank_code,
'account_number' => $account
]
]
]);
if ($response->status() == 200) {
return json_decode($response);
}
return false;
}
}
================================================
FILE: submissions/chiconnect-laravel-web-app/app/Support/Chiconnect/Payout.php
================================================
config('chimoney.api_key'),
'accept' => 'application/json',
'content-type' => 'application/json',
])->post('https://api.chimoney.io/v0.2/payouts/airtime', [
'subAccount' => $sub_account, // alaklsjfal-asdfl-asdf-asf
'airtimes' => [
[
'countryToSend' => $country, // Nigeria
'phoneNumber' => $phone, // +2345678909876
'valueInUSD' => $valueInUSD, // >= 1
]
]
]);
if ($response->status() == 200) {
return json_decode($response)->data->data;
}
return false;
}
public static function Bank(string $sub_account, string $country, string $bank_code, string $account_number, string $valueInUSD, string $reference)
{
// dd($sub_account, $country, $bank_code, $account_number, $valueInUSD, $reference);
$response = Http::withHeaders([
'X-API-KEY' => config('chimoney.api_key'),
'accept' => 'application/json',
'content-type' => 'application/json',
])->post('https://api.chimoney.io/v0.2/payouts/bank', [
'subAccount' => $sub_account,
'banks' => [
[
'countryToSend' => $country, // Nigeria
'account_bank' => $bank_code, // 058 for Guaranty Trust Bank
'account_number' => $account_number, // 0234567890
'valueInUSD' => $valueInUSD, // >= 1
'reference' => $reference //{generated uuid}
]
]
]);
if ($response->status() == 200) {
return json_decode($response)->data->chimoneys;
}
return false;
}
public static function Status(string $sub_account, string $chiRef)
{
$response = Http::withHeaders([
'X-API-KEY' => config('chimoney.api_key'),
'accept' => 'application/json',
'content-type' => 'application/json',
])->post('https://api.chimoney.io/v0.2/payouts/status', [
'subAccount' => $sub_account,
'chiRef' => $chiRef
]);
if ($response->status() == 200) {
return json_decode($response)->data;
}
return false;
// SAMPLE RESPONSE
// AIRTIME
// {
// "status": "success",
// "data": {
// "id": "hPbvs2CICyWpArWCxJba",
// "chimoney": 1000,
// "payout": {
// "phoneNumber": "+234567890343",
// "errorMessage": "None",
// "status": "Sent",
// "amount": "NGN 550.0000",
// "requestId": "ATQid_2222f6beff1d2f4c5cd99e9f2d9f17c6"
// },
// "enabledToRedeem": [
// "airtime"
// ],
// "valueInUSD": 1,
// "chiRef": "84cacc48-1da9-4d89-b93a-e89705d946c5",
// "integration": {
// "appID": "pIsRyLXuKHBVlWzdVAYb"
// },
// "type": "airtime",
// "countryToSend": "Nigeria",
// "issueID": "d6e267f7-c4c5-435a-8f2a-0ee413026dfc_1_1666296502376",
// "phoneNumber": "+23456789086",
// "issuer": "d6e267f7-c4c5-435a-8f2a-0ee413026dfc",
// "status": "redeemed",
// "issueDate": "2022-10-20T20:08:26.280Z"
// }
// }
//
// BANK
// {
// "status": "success",
// "data": {
// "id": "asdfasfadfaf",
// "status": "redeemed",
// "valueInUSD": 1,
// "chimoney": 1000,
// "countryToSend": "Nigeria",
// "account_bank": "058",
// "payout": {
// "account_number": "02423423424",
// "is_approved": 1,
// "currency": "NGN",
// "bank_name": "GTBANK PLC",
// "status": "SUCCESSFUL",
// "complete_message": "Transaction was successful",
// "amount": 550,
// "created_at": "2022-10-20T20:16:50.000Z",
// "id": 35627209,
// "meta": {
// "valueInUSD": 1,
// "type": "bank",
// "chiRef": "b7f64d59-c521-4fe3-a756-26ac83d55002",
// "country": "NG",
// "currency": "NGN"
// },
// "fullname": "LAST_NAME, FIRST_NAME OTHER_NAMES",
// "reference": "b7f64d59-c521-4fe3-a756-26ac83d55002_1666297009694",
// "bank_code": "058",
// "requires_approval": 0
// },
// "integration": {
// "appID": "pIsRyLXuKHBVlWzdVAYb"
// },
// "issueID": "d6e267f7-c4c5-435a-8f2a-0ee413026dfc_1_1666297006803",
// "type": "bank",
// "enabledToRedeem": [
// "bank"
// ],
// "fee": 0,
// "account_number": "20040439434",
// "issuer": "d6e267f7-c4c5-435a-8f2a-0ee413026dfc",
// "chiRef": "b7f64d59-c521-4fe3-a756-26ac83d55002",
// "issueDate": "2022-10-20T20:16:51.359Z"
// }
// }
}
}
================================================
FILE: submissions/chiconnect-laravel-web-app/app/Support/Chiconnect/SubAccount.php
================================================
config('chimoney.api_key'),
'accept' => 'application/json',
'content-type' => 'application/json',
])->post('https://api.chimoney.io/v0.2/sub-account/create', [
'name' => $name,
'email' => $email
]);
if($response->status() == 200){
return json_decode($response)->data->uid;
}
return null;
}
}
================================================
FILE: submissions/chiconnect-laravel-web-app/app/Support/Chiconnect/Wallet.php
================================================
config('chimoney.api_key'),
'accept' => 'application/json',
'content-type' => 'application/json',
])->post('https://api.chimoney.io/v0.2/wallets/list', [
'subAccount' => $sub_account,
]);
if($response->status() == 200){
return json_decode($response)->data;
}
return [];
}
public static function fetchType(string $type, string $sub_account)
{
$wallets = self::fetchAll($sub_account);
return collect($wallets)->where('type', $type)->first();
}
public static function fetchBalance(string $wallet_id, string $sub_account)
{
$response = Http::withHeaders([
'X-API-KEY' => config('chimoney.api_key'),
'accept' => 'application/json',
'content-type' => 'application/json',
])->post('https://api.chimoney.io/v0.2/wallets/lookup', [
'subAccount' => $sub_account,
'walletID' => $wallet_id
]);
return json_decode($response)->data->balance ?? 0;
}
}
================================================
FILE: submissions/chiconnect-laravel-web-app/app/Support/Helpers.php
================================================
user()->type == 'admin' ? true : false;
}
}
if (!function_exists('getCountryCodes')) {
function getCountryCodes()
{
return config('country_code');
}
}
================================================
FILE: submissions/chiconnect-laravel-web-app/app/View/Components/AppLayout.php
================================================
make(Illuminate\Contracts\Console\Kernel::class);
$status = $kernel->handle(
$input = new Symfony\Component\Console\Input\ArgvInput,
new Symfony\Component\Console\Output\ConsoleOutput
);
/*
|--------------------------------------------------------------------------
| Shutdown The Application
|--------------------------------------------------------------------------
|
| Once Artisan has finished running, we will fire off the shutdown events
| so that any final work may be done by the application before we shut
| down the process. This is the last thing to happen to the request.
|
*/
$kernel->terminate($input, $status);
exit($status);
================================================
FILE: submissions/chiconnect-laravel-web-app/bootstrap/app.php
================================================
singleton(
Illuminate\Contracts\Http\Kernel::class,
App\Http\Kernel::class
);
$app->singleton(
Illuminate\Contracts\Console\Kernel::class,
App\Console\Kernel::class
);
$app->singleton(
Illuminate\Contracts\Debug\ExceptionHandler::class,
App\Exceptions\Handler::class
);
/*
|--------------------------------------------------------------------------
| Return The Application
|--------------------------------------------------------------------------
|
| This script returns the application instance. The instance is given to
| the calling script so we can separate the building of the instances
| from the actual running of the application and sending responses.
|
*/
return $app;
================================================
FILE: submissions/chiconnect-laravel-web-app/bootstrap/cache/.gitignore
================================================
*
!.gitignore
================================================
FILE: submissions/chiconnect-laravel-web-app/composer.json
================================================
{
"name": "laravel/laravel",
"type": "project",
"description": "The Laravel Framework.",
"keywords": ["framework", "laravel"],
"license": "MIT",
"require": {
"php": "^8.0.2",
"guzzlehttp/guzzle": "^7.2",
"laravel/framework": "^9.19",
"laravel/sanctum": "^3.0",
"laravel/tinker": "^2.7",
"livewire/livewire": "^2.10"
},
"require-dev": {
"fakerphp/faker": "^1.9.1",
"laravel/breeze": "^1.14",
"laravel/pint": "^1.0",
"laravel/sail": "^1.0.1",
"mockery/mockery": "^1.4.4",
"nunomaduro/collision": "^6.1",
"phpunit/phpunit": "^9.5.10",
"spatie/laravel-ignition": "^1.0"
},
"autoload": {
"psr-4": {
"App\\": "app/",
"Database\\Factories\\": "database/factories/",
"Database\\Seeders\\": "database/seeders/"
},
"files": [
"app/Support/Helpers.php"
]
},
"autoload-dev": {
"psr-4": {
"Tests\\": "tests/"
}
},
"scripts": {
"post-autoload-dump": [
"Illuminate\\Foundation\\ComposerScripts::postAutoloadDump",
"@php artisan package:discover --ansi"
],
"post-update-cmd": [
"@php artisan vendor:publish --tag=laravel-assets --ansi --force"
],
"post-root-package-install": [
"@php -r \"file_exists('.env') || copy('.env.example', '.env');\""
],
"post-create-project-cmd": [
"@php artisan key:generate --ansi"
]
},
"extra": {
"laravel": {
"dont-discover": []
}
},
"config": {
"optimize-autoloader": true,
"preferred-install": "dist",
"sort-packages": true,
"allow-plugins": {
"pestphp/pest-plugin": true
}
},
"minimum-stability": "dev",
"prefer-stable": true
}
================================================
FILE: submissions/chiconnect-laravel-web-app/config/app.php
================================================
env('APP_NAME', 'Laravel'),
/*
|--------------------------------------------------------------------------
| Application Environment
|--------------------------------------------------------------------------
|
| This value determines the "environment" your application is currently
| running in. This may determine how you prefer to configure various
| services the application utilizes. Set this in your ".env" file.
|
*/
'env' => env('APP_ENV', 'production'),
/*
|--------------------------------------------------------------------------
| Application Debug Mode
|--------------------------------------------------------------------------
|
| When your application is in debug mode, detailed error messages with
| stack traces will be shown on every error that occurs within your
| application. If disabled, a simple generic error page is shown.
|
*/
'debug' => (bool) env('APP_DEBUG', false),
/*
|--------------------------------------------------------------------------
| Application URL
|--------------------------------------------------------------------------
|
| This URL is used by the console to properly generate URLs when using
| the Artisan command line tool. You should set this to the root of
| your application so that it is used when running Artisan tasks.
|
*/
'url' => env('APP_URL', 'http://localhost'),
'asset_url' => env('ASSET_URL'),
/*
|--------------------------------------------------------------------------
| Application Timezone
|--------------------------------------------------------------------------
|
| Here you may specify the default timezone for your application, which
| will be used by the PHP date and date-time functions. We have gone
| ahead and set this to a sensible default for you out of the box.
|
*/
'timezone' => 'UTC',
/*
|--------------------------------------------------------------------------
| Application Locale Configuration
|--------------------------------------------------------------------------
|
| The application locale determines the default locale that will be used
| by the translation service provider. You are free to set this value
| to any of the locales which will be supported by the application.
|
*/
'locale' => 'en',
/*
|--------------------------------------------------------------------------
| Application Fallback Locale
|--------------------------------------------------------------------------
|
| The fallback locale determines the locale to use when the current one
| is not available. You may change the value to correspond to any of
| the language folders that are provided through your application.
|
*/
'fallback_locale' => 'en',
/*
|--------------------------------------------------------------------------
| Faker Locale
|--------------------------------------------------------------------------
|
| This locale will be used by the Faker PHP library when generating fake
| data for your database seeds. For example, this will be used to get
| localized telephone numbers, street address information and more.
|
*/
'faker_locale' => 'en_US',
/*
|--------------------------------------------------------------------------
| Encryption Key
|--------------------------------------------------------------------------
|
| This key is used by the Illuminate encrypter service and should be set
| to a random, 32 character string, otherwise these encrypted strings
| will not be safe. Please do this before deploying an application!
|
*/
'key' => env('APP_KEY'),
'cipher' => 'AES-256-CBC',
/*
|--------------------------------------------------------------------------
| Maintenance Mode Driver
|--------------------------------------------------------------------------
|
| These configuration options determine the driver used to determine and
| manage Laravel's "maintenance mode" status. The "cache" driver will
| allow maintenance mode to be controlled across multiple machines.
|
| Supported drivers: "file", "cache"
|
*/
'maintenance' => [
'driver' => 'file',
// 'store' => 'redis',
],
/*
|--------------------------------------------------------------------------
| Autoloaded Service Providers
|--------------------------------------------------------------------------
|
| The service providers listed here will be automatically loaded on the
| request to your application. Feel free to add your own services to
| this array to grant expanded functionality to your applications.
|
*/
'providers' => [
/*
* Laravel Framework Service Providers...
*/
Illuminate\Auth\AuthServiceProvider::class,
Illuminate\Broadcasting\BroadcastServiceProvider::class,
Illuminate\Bus\BusServiceProvider::class,
Illuminate\Cache\CacheServiceProvider::class,
Illuminate\Foundation\Providers\ConsoleSupportServiceProvider::class,
Illuminate\Cookie\CookieServiceProvider::class,
Illuminate\Database\DatabaseServiceProvider::class,
Illuminate\Encryption\EncryptionServiceProvider::class,
Illuminate\Filesystem\FilesystemServiceProvider::class,
Illuminate\Foundation\Providers\FoundationServiceProvider::class,
Illuminate\Hashing\HashServiceProvider::class,
Illuminate\Mail\MailServiceProvider::class,
Illuminate\Notifications\NotificationServiceProvider::class,
Illuminate\Pagination\PaginationServiceProvider::class,
Illuminate\Pipeline\PipelineServiceProvider::class,
Illuminate\Queue\QueueServiceProvider::class,
Illuminate\Redis\RedisServiceProvider::class,
Illuminate\Auth\Passwords\PasswordResetServiceProvider::class,
Illuminate\Session\SessionServiceProvider::class,
Illuminate\Translation\TranslationServiceProvider::class,
Illuminate\Validation\ValidationServiceProvider::class,
Illuminate\View\ViewServiceProvider::class,
/*
* Package Service Providers...
*/
/*
* Application Service Providers...
*/
App\Providers\AppServiceProvider::class,
App\Providers\AuthServiceProvider::class,
// App\Providers\BroadcastServiceProvider::class,
App\Providers\EventServiceProvider::class,
App\Providers\RouteServiceProvider::class,
],
/*
|--------------------------------------------------------------------------
| Class Aliases
|--------------------------------------------------------------------------
|
| This array of class aliases will be registered when this application
| is started. However, feel free to register as many as you wish as
| the aliases are "lazy" loaded so they don't hinder performance.
|
*/
'aliases' => Facade::defaultAliases()->merge([
// 'ExampleClass' => App\Example\ExampleClass::class,
])->toArray(),
];
================================================
FILE: submissions/chiconnect-laravel-web-app/config/auth.php
================================================
[
'guard' => 'web',
'passwords' => 'users',
],
/*
|--------------------------------------------------------------------------
| Authentication Guards
|--------------------------------------------------------------------------
|
| Next, you may define every authentication guard for your application.
| Of course, a great default configuration has been defined for you
| here which uses session storage and the Eloquent user provider.
|
| All authentication drivers have a user provider. This defines how the
| users are actually retrieved out of your database or other storage
| mechanisms used by this application to persist your user's data.
|
| Supported: "session"
|
*/
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
],
/*
|--------------------------------------------------------------------------
| User Providers
|--------------------------------------------------------------------------
|
| All authentication drivers have a user provider. This defines how the
| users are actually retrieved out of your database or other storage
| mechanisms used by this application to persist your user's data.
|
| If you have multiple user tables or models you may configure multiple
| sources which represent each model / table. These sources may then
| be assigned to any extra authentication guards you have defined.
|
| Supported: "database", "eloquent"
|
*/
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\Models\User::class,
],
// 'users' => [
// 'driver' => 'database',
// 'table' => 'users',
// ],
],
/*
|--------------------------------------------------------------------------
| Resetting Passwords
|--------------------------------------------------------------------------
|
| You may specify multiple password reset configurations if you have more
| than one user table or model in the application and you want to have
| separate password reset settings based on the specific user types.
|
| The expire time is the number of minutes that each reset token will be
| considered valid. This security feature keeps tokens short-lived so
| they have less time to be guessed. You may change this as needed.
|
*/
'passwords' => [
'users' => [
'provider' => 'users',
'table' => 'password_resets',
'expire' => 60,
'throttle' => 60,
],
],
/*
|--------------------------------------------------------------------------
| Password Confirmation Timeout
|--------------------------------------------------------------------------
|
| Here you may define the amount of seconds before a password confirmation
| times out and the user is prompted to re-enter their password via the
| confirmation screen. By default, the timeout lasts for three hours.
|
*/
'password_timeout' => 10800,
];
================================================
FILE: submissions/chiconnect-laravel-web-app/config/broadcasting.php
================================================
env('BROADCAST_DRIVER', 'null'),
/*
|--------------------------------------------------------------------------
| Broadcast Connections
|--------------------------------------------------------------------------
|
| Here you may define all of the broadcast connections that will be used
| to broadcast events to other systems or over websockets. Samples of
| each available type of connection are provided inside this array.
|
*/
'connections' => [
'pusher' => [
'driver' => 'pusher',
'key' => env('PUSHER_APP_KEY'),
'secret' => env('PUSHER_APP_SECRET'),
'app_id' => env('PUSHER_APP_ID'),
'options' => [
'host' => env('PUSHER_HOST', 'api-'.env('PUSHER_APP_CLUSTER', 'mt1').'.pusher.com') ?: 'api-'.env('PUSHER_APP_CLUSTER', 'mt1').'.pusher.com',
'port' => env('PUSHER_PORT', 443),
'scheme' => env('PUSHER_SCHEME', 'https'),
'encrypted' => true,
'useTLS' => env('PUSHER_SCHEME', 'https') === 'https',
],
'client_options' => [
// Guzzle client options: https://docs.guzzlephp.org/en/stable/request-options.html
],
],
'ably' => [
'driver' => 'ably',
'key' => env('ABLY_KEY'),
],
'redis' => [
'driver' => 'redis',
'connection' => 'default',
],
'log' => [
'driver' => 'log',
],
'null' => [
'driver' => 'null',
],
],
];
================================================
FILE: submissions/chiconnect-laravel-web-app/config/cache.php
================================================
env('CACHE_DRIVER', 'file'),
/*
|--------------------------------------------------------------------------
| Cache Stores
|--------------------------------------------------------------------------
|
| Here you may define all of the cache "stores" for your application as
| well as their drivers. You may even define multiple stores for the
| same cache driver to group types of items stored in your caches.
|
| Supported drivers: "apc", "array", "database", "file",
| "memcached", "redis", "dynamodb", "octane", "null"
|
*/
'stores' => [
'apc' => [
'driver' => 'apc',
],
'array' => [
'driver' => 'array',
'serialize' => false,
],
'database' => [
'driver' => 'database',
'table' => 'cache',
'connection' => null,
'lock_connection' => null,
],
'file' => [
'driver' => 'file',
'path' => storage_path('framework/cache/data'),
],
'memcached' => [
'driver' => 'memcached',
'persistent_id' => env('MEMCACHED_PERSISTENT_ID'),
'sasl' => [
env('MEMCACHED_USERNAME'),
env('MEMCACHED_PASSWORD'),
],
'options' => [
// Memcached::OPT_CONNECT_TIMEOUT => 2000,
],
'servers' => [
[
'host' => env('MEMCACHED_HOST', '127.0.0.1'),
'port' => env('MEMCACHED_PORT', 11211),
'weight' => 100,
],
],
],
'redis' => [
'driver' => 'redis',
'connection' => 'cache',
'lock_connection' => 'default',
],
'dynamodb' => [
'driver' => 'dynamodb',
'key' => env('AWS_ACCESS_KEY_ID'),
'secret' => env('AWS_SECRET_ACCESS_KEY'),
'region' => env('AWS_DEFAULT_REGION', 'us-east-1'),
'table' => env('DYNAMODB_CACHE_TABLE', 'cache'),
'endpoint' => env('DYNAMODB_ENDPOINT'),
],
'octane' => [
'driver' => 'octane',
],
],
/*
|--------------------------------------------------------------------------
| Cache Key Prefix
|--------------------------------------------------------------------------
|
| When utilizing the APC, database, memcached, Redis, or DynamoDB cache
| stores there might be other applications using the same cache. For
| that reason, you may prefix every cache key to avoid collisions.
|
*/
'prefix' => env('CACHE_PREFIX', Str::slug(env('APP_NAME', 'laravel'), '_').'_cache_'),
];
================================================
FILE: submissions/chiconnect-laravel-web-app/config/chimoney.php
================================================
env('CHIMONEY_API_KEY'),
'main_account_id' => env('CHIMONEY_MAIN_ACCOUNT_ID'),
];
================================================
FILE: submissions/chiconnect-laravel-web-app/config/cors.php
================================================
['api/*', 'sanctum/csrf-cookie'],
'allowed_methods' => ['*'],
'allowed_origins' => ['*'],
'allowed_origins_patterns' => [],
'allowed_headers' => ['*'],
'exposed_headers' => [],
'max_age' => 0,
'supports_credentials' => false,
];
================================================
FILE: submissions/chiconnect-laravel-web-app/config/country_code.php
================================================
"Afghanistan",
"AX" => "Aland Islands",
"AL" => "Albania",
"DZ" => "Algeria",
"AS" => "American Samoa",
"AD" => "Andorra",
"AO" => "Angola",
"AI" => "Anguilla",
"AQ" => "Antarctica",
"AG" => "Antigua And Barbuda",
"AR" => "Argentina",
"AM" => "Armenia",
"AW" => "Aruba",
"AU" => "Australia",
"AT" => "Austria",
"AZ" => "Azerbaijan",
"BS" => "Bahamas",
"BH" => "Bahrain",
"BD" => "Bangladesh",
"BB" => "Barbados",
"BY" => "Belarus",
"BE" => "Belgium",
"BZ" => "Belize",
"BJ" => "Benin",
"BM" => "Bermuda",
"BT" => "Bhutan",
"BO" => "Bolivia",
"BA" => "Bosnia And Herzegovina",
"BW" => "Botswana",
"BV" => "Bouvet Island",
"BR" => "Brazil",
"IO" => "British Indian Ocean Territory",
"BN" => "Brunei Darussalam",
"BG" => "Bulgaria",
"BF" => "Burkina Faso",
"BI" => "Burundi",
"KH" => "Cambodia",
"CM" => "Cameroon",
"CA" => "Canada",
"CV" => "Cape Verde",
"KY" => "Cayman Islands",
"CF" => "Central African Republic",
"TD" => "Chad",
"CL" => "Chile",
"CN" => "China",
"CX" => "Christmas Island",
"CC" => "Cocos (Keeling) Islands",
"CO" => "Colombia",
"KM" => "Comoros",
"CG" => "Congo",
"CD" => "Congo, Democratic Republic",
"CK" => "Cook Islands",
"CR" => "Costa Rica",
"CI" => "Cote D\"Ivoire",
"HR" => "Croatia",
"CU" => "Cuba",
"CY" => "Cyprus",
"CZ" => "Czech Republic",
"DK" => "Denmark",
"DJ" => "Djibouti",
"DM" => "Dominica",
"DO" => "Dominican Republic",
"EC" => "Ecuador",
"EG" => "Egypt",
"SV" => "El Salvador",
"GQ" => "Equatorial Guinea",
"ER" => "Eritrea",
"EE" => "Estonia",
"ET" => "Ethiopia",
"FK" => "Falkland Islands (Malvinas)",
"FO" => "Faroe Islands",
"FJ" => "Fiji",
"FI" => "Finland",
"FR" => "France",
"GF" => "French Guiana",
"PF" => "French Polynesia",
"TF" => "French Southern Territories",
"GA" => "Gabon",
"GM" => "Gambia",
"GE" => "Georgia",
"DE" => "Germany",
"GH" => "Ghana",
"GI" => "Gibraltar",
"GR" => "Greece",
"GL" => "Greenland",
"GD" => "Grenada",
"GP" => "Guadeloupe",
"GU" => "Guam",
"GT" => "Guatemala",
"GG" => "Guernsey",
"GN" => "Guinea",
"GW" => "Guinea-Bissau",
"GY" => "Guyana",
"HT" => "Haiti",
"HM" => "Heard Island & Mcdonald Islands",
"VA" => "Holy See (Vatican City State)",
"HN" => "Honduras",
"HK" => "Hong Kong",
"HU" => "Hungary",
"IS" => "Iceland",
"IN" => "India",
"ID" => "Indonesia",
"IR" => "Iran, Islamic Republic Of",
"IQ" => "Iraq",
"IE" => "Ireland",
"IM" => "Isle Of Man",
"IL" => "Israel",
"IT" => "Italy",
"JM" => "Jamaica",
"JP" => "Japan",
"JE" => "Jersey",
"JO" => "Jordan",
"KZ" => "Kazakhstan",
"KE" => "Kenya",
"KI" => "Kiribati",
"KR" => "Korea",
"KP" => "North Korea",
"KW" => "Kuwait",
"KG" => "Kyrgyzstan",
"LA" => "Lao People\"s Democratic Republic",
"LV" => "Latvia",
"LB" => "Lebanon",
"LS" => "Lesotho",
"LR" => "Liberia",
"LY" => "Libyan Arab Jamahiriya",
"LI" => "Liechtenstein",
"LT" => "Lithuania",
"LU" => "Luxembourg",
"MO" => "Macao",
"MK" => "Macedonia",
"MG" => "Madagascar",
"MW" => "Malawi",
"MY" => "Malaysia",
"MV" => "Maldives",
"ML" => "Mali",
"MT" => "Malta",
"MH" => "Marshall Islands",
"MQ" => "Martinique",
"MR" => "Mauritania",
"MU" => "Mauritius",
"YT" => "Mayotte",
"MX" => "Mexico",
"FM" => "Micronesia, Federated States Of",
"MD" => "Moldova",
"MC" => "Monaco",
"MN" => "Mongolia",
"ME" => "Montenegro",
"MS" => "Montserrat",
"MA" => "Morocco",
"MZ" => "Mozambique",
"MM" => "Myanmar",
"NA" => "Namibia",
"NR" => "Nauru",
"NP" => "Nepal",
"NL" => "Netherlands",
"AN" => "Netherlands Antilles",
"NC" => "New Caledonia",
"NZ" => "New Zealand",
"NI" => "Nicaragua",
"NE" => "Niger",
"NG" => "Nigeria",
"NU" => "Niue",
"NF" => "Norfolk Island",
"MP" => "Northern Mariana Islands",
"NO" => "Norway",
"OM" => "Oman",
"PK" => "Pakistan",
"PW" => "Palau",
"PS" => "Palestinian Territory, Occupied",
"PA" => "Panama",
"PG" => "Papua New Guinea",
"PY" => "Paraguay",
"PE" => "Peru",
"PH" => "Philippines",
"PN" => "Pitcairn",
"PL" => "Poland",
"PT" => "Portugal",
"PR" => "Puerto Rico",
"QA" => "Qatar",
"RE" => "Reunion",
"RO" => "Romania",
"RU" => "Russian Federation",
"RW" => "Rwanda",
"BL" => "Saint Barthelemy",
"SH" => "Saint Helena",
"KN" => "Saint Kitts And Nevis",
"LC" => "Saint Lucia",
"MF" => "Saint Martin",
"PM" => "Saint Pierre And Miquelon",
"VC" => "Saint Vincent And Grenadines",
"WS" => "Samoa",
"SM" => "San Marino",
"ST" => "Sao Tome And Principe",
"SA" => "Saudi Arabia",
"SN" => "Senegal",
"RS" => "Serbia",
"SC" => "Seychelles",
"SL" => "Sierra Leone",
"SG" => "Singapore",
"SK" => "Slovakia",
"SI" => "Slovenia",
"SB" => "Solomon Islands",
"SO" => "Somalia",
"ZA" => "South Africa",
"GS" => "South Georgia And Sandwich Isl.",
"ES" => "Spain",
"LK" => "Sri Lanka",
"SD" => "Sudan",
"SR" => "Suriname",
"SJ" => "Svalbard And Jan Mayen",
"SZ" => "Swaziland",
"SE" => "Sweden",
"CH" => "Switzerland",
"SY" => "Syrian Arab Republic",
"TW" => "Taiwan",
"TJ" => "Tajikistan",
"TZ" => "Tanzania",
"TH" => "Thailand",
"TL" => "Timor-Leste",
"TG" => "Togo",
"TK" => "Tokelau",
"TO" => "Tonga",
"TT" => "Trinidad And Tobago",
"TN" => "Tunisia",
"TR" => "Turkey",
"TM" => "Turkmenistan",
"TC" => "Turks And Caicos Islands",
"TV" => "Tuvalu",
"UG" => "Uganda",
"UA" => "Ukraine",
"AE" => "United Arab Emirates",
"GB" => "United Kingdom",
"US" => "United States",
"UM" => "United States Outlying Islands",
"UY" => "Uruguay",
"UZ" => "Uzbekistan",
"VU" => "Vanuatu",
"VE" => "Venezuela",
"VN" => "Vietnam",
"VG" => "Virgin Islands, British",
"VI" => "Virgin Islands, U.S.",
"WF" => "Wallis And Futuna",
"EH" => "Western Sahara",
"YE" => "Yemen",
"ZM" => "Zambia",
"ZW" => "Zimbabwe"
];
================================================
FILE: submissions/chiconnect-laravel-web-app/config/database.php
================================================
env('DB_CONNECTION', 'mysql'),
/*
|--------------------------------------------------------------------------
| Database Connections
|--------------------------------------------------------------------------
|
| Here are each of the database connections setup for your application.
| Of course, examples of configuring each database platform that is
| supported by Laravel is shown below to make development simple.
|
|
| All database work in Laravel is done through the PHP PDO facilities
| so make sure you have the driver for your particular database of
| choice installed on your machine before you begin development.
|
*/
'connections' => [
'sqlite' => [
'driver' => 'sqlite',
'url' => env('DATABASE_URL'),
'database' => env('DB_DATABASE', database_path('database.sqlite')),
'prefix' => '',
'foreign_key_constraints' => env('DB_FOREIGN_KEYS', true),
],
'mysql' => [
'driver' => 'mysql',
'url' => env('DATABASE_URL'),
'host' => env('DB_HOST', '127.0.0.1'),
'port' => env('DB_PORT', '3306'),
'database' => env('DB_DATABASE', 'forge'),
'username' => env('DB_USERNAME', 'forge'),
'password' => env('DB_PASSWORD', ''),
'unix_socket' => env('DB_SOCKET', ''),
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',
'prefix' => '',
'prefix_indexes' => true,
'strict' => true,
'engine' => null,
'options' => extension_loaded('pdo_mysql') ? array_filter([
PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'),
]) : [],
],
'pgsql' => [
'driver' => 'pgsql',
'url' => env('DATABASE_URL'),
'host' => env('DB_HOST', '127.0.0.1'),
'port' => env('DB_PORT', '5432'),
'database' => env('DB_DATABASE', 'forge'),
'username' => env('DB_USERNAME', 'forge'),
'password' => env('DB_PASSWORD', ''),
'charset' => 'utf8',
'prefix' => '',
'prefix_indexes' => true,
'search_path' => 'public',
'sslmode' => 'prefer',
],
'sqlsrv' => [
'driver' => 'sqlsrv',
'url' => env('DATABASE_URL'),
'host' => env('DB_HOST', 'localhost'),
'port' => env('DB_PORT', '1433'),
'database' => env('DB_DATABASE', 'forge'),
'username' => env('DB_USERNAME', 'forge'),
'password' => env('DB_PASSWORD', ''),
'charset' => 'utf8',
'prefix' => '',
'prefix_indexes' => true,
// 'encrypt' => env('DB_ENCRYPT', 'yes'),
// 'trust_server_certificate' => env('DB_TRUST_SERVER_CERTIFICATE', 'false'),
],
],
/*
|--------------------------------------------------------------------------
| Migration Repository Table
|--------------------------------------------------------------------------
|
| This table keeps track of all the migrations that have already run for
| your application. Using this information, we can determine which of
| the migrations on disk haven't actually been run in the database.
|
*/
'migrations' => 'migrations',
/*
|--------------------------------------------------------------------------
| Redis Databases
|--------------------------------------------------------------------------
|
| Redis is an open source, fast, and advanced key-value store that also
| provides a richer body of commands than a typical key-value system
| such as APC or Memcached. Laravel makes it easy to dig right in.
|
*/
'redis' => [
'client' => env('REDIS_CLIENT', 'phpredis'),
'options' => [
'cluster' => env('REDIS_CLUSTER', 'redis'),
'prefix' => env('REDIS_PREFIX', Str::slug(env('APP_NAME', 'laravel'), '_').'_database_'),
],
'default' => [
'url' => env('REDIS_URL'),
'host' => env('REDIS_HOST', '127.0.0.1'),
'username' => env('REDIS_USERNAME'),
'password' => env('REDIS_PASSWORD'),
'port' => env('REDIS_PORT', '6379'),
'database' => env('REDIS_DB', '0'),
],
'cache' => [
'url' => env('REDIS_URL'),
'host' => env('REDIS_HOST', '127.0.0.1'),
'username' => env('REDIS_USERNAME'),
'password' => env('REDIS_PASSWORD'),
'port' => env('REDIS_PORT', '6379'),
'database' => env('REDIS_CACHE_DB', '1'),
],
],
];
================================================
FILE: submissions/chiconnect-laravel-web-app/config/filesystems.php
================================================
env('FILESYSTEM_DISK', 'local'),
/*
|--------------------------------------------------------------------------
| Filesystem Disks
|--------------------------------------------------------------------------
|
| Here you may configure as many filesystem "disks" as you wish, and you
| may even configure multiple disks of the same driver. Defaults have
| been set up for each driver as an example of the required values.
|
| Supported Drivers: "local", "ftp", "sftp", "s3"
|
*/
'disks' => [
'local' => [
'driver' => 'local',
'root' => storage_path('app'),
'throw' => false,
],
'public' => [
'driver' => 'local',
'root' => storage_path('app/public'),
'url' => env('APP_URL').'/storage',
'visibility' => 'public',
'throw' => false,
],
's3' => [
'driver' => 's3',
'key' => env('AWS_ACCESS_KEY_ID'),
'secret' => env('AWS_SECRET_ACCESS_KEY'),
'region' => env('AWS_DEFAULT_REGION'),
'bucket' => env('AWS_BUCKET'),
'url' => env('AWS_URL'),
'endpoint' => env('AWS_ENDPOINT'),
'use_path_style_endpoint' => env('AWS_USE_PATH_STYLE_ENDPOINT', false),
'throw' => false,
],
],
/*
|--------------------------------------------------------------------------
| Symbolic Links
|--------------------------------------------------------------------------
|
| Here you may configure the symbolic links that will be created when the
| `storage:link` Artisan command is executed. The array keys should be
| the locations of the links and the values should be their targets.
|
*/
'links' => [
public_path('storage') => storage_path('app/public'),
],
];
================================================
FILE: submissions/chiconnect-laravel-web-app/config/hashing.php
================================================
'bcrypt',
/*
|--------------------------------------------------------------------------
| Bcrypt Options
|--------------------------------------------------------------------------
|
| Here you may specify the configuration options that should be used when
| passwords are hashed using the Bcrypt algorithm. This will allow you
| to control the amount of time it takes to hash the given password.
|
*/
'bcrypt' => [
'rounds' => env('BCRYPT_ROUNDS', 10),
],
/*
|--------------------------------------------------------------------------
| Argon Options
|--------------------------------------------------------------------------
|
| Here you may specify the configuration options that should be used when
| passwords are hashed using the Argon algorithm. These will allow you
| to control the amount of time it takes to hash the given password.
|
*/
'argon' => [
'memory' => 65536,
'threads' => 1,
'time' => 4,
],
];
================================================
FILE: submissions/chiconnect-laravel-web-app/config/logging.php
================================================
env('LOG_CHANNEL', 'stack'),
/*
|--------------------------------------------------------------------------
| Deprecations Log Channel
|--------------------------------------------------------------------------
|
| This option controls the log channel that should be used to log warnings
| regarding deprecated PHP and library features. This allows you to get
| your application ready for upcoming major versions of dependencies.
|
*/
'deprecations' => [
'channel' => env('LOG_DEPRECATIONS_CHANNEL', 'null'),
'trace' => false,
],
/*
|--------------------------------------------------------------------------
| Log Channels
|--------------------------------------------------------------------------
|
| Here you may configure the log channels for your application. Out of
| the box, Laravel uses the Monolog PHP logging library. This gives
| you a variety of powerful log handlers / formatters to utilize.
|
| Available Drivers: "single", "daily", "slack", "syslog",
| "errorlog", "monolog",
| "custom", "stack"
|
*/
'channels' => [
'stack' => [
'driver' => 'stack',
'channels' => ['single'],
'ignore_exceptions' => false,
],
'single' => [
'driver' => 'single',
'path' => storage_path('logs/laravel.log'),
'level' => env('LOG_LEVEL', 'debug'),
],
'daily' => [
'driver' => 'daily',
'path' => storage_path('logs/laravel.log'),
'level' => env('LOG_LEVEL', 'debug'),
'days' => 14,
],
'slack' => [
'driver' => 'slack',
'url' => env('LOG_SLACK_WEBHOOK_URL'),
'username' => 'Laravel Log',
'emoji' => ':boom:',
'level' => env('LOG_LEVEL', 'critical'),
],
'papertrail' => [
'driver' => 'monolog',
'level' => env('LOG_LEVEL', 'debug'),
'handler' => env('LOG_PAPERTRAIL_HANDLER', SyslogUdpHandler::class),
'handler_with' => [
'host' => env('PAPERTRAIL_URL'),
'port' => env('PAPERTRAIL_PORT'),
'connectionString' => 'tls://'.env('PAPERTRAIL_URL').':'.env('PAPERTRAIL_PORT'),
],
],
'stderr' => [
'driver' => 'monolog',
'level' => env('LOG_LEVEL', 'debug'),
'handler' => StreamHandler::class,
'formatter' => env('LOG_STDERR_FORMATTER'),
'with' => [
'stream' => 'php://stderr',
],
],
'syslog' => [
'driver' => 'syslog',
'level' => env('LOG_LEVEL', 'debug'),
],
'errorlog' => [
'driver' => 'errorlog',
'level' => env('LOG_LEVEL', 'debug'),
],
'null' => [
'driver' => 'monolog',
'handler' => NullHandler::class,
],
'emergency' => [
'path' => storage_path('logs/laravel.log'),
],
],
];
================================================
FILE: submissions/chiconnect-laravel-web-app/config/mail.php
================================================
env('MAIL_MAILER', 'smtp'),
/*
|--------------------------------------------------------------------------
| Mailer Configurations
|--------------------------------------------------------------------------
|
| Here you may configure all of the mailers used by your application plus
| their respective settings. Several examples have been configured for
| you and you are free to add your own as your application requires.
|
| Laravel supports a variety of mail "transport" drivers to be used while
| sending an e-mail. You will specify which one you are using for your
| mailers below. You are free to add additional mailers as required.
|
| Supported: "smtp", "sendmail", "mailgun", "ses",
| "postmark", "log", "array", "failover"
|
*/
'mailers' => [
'smtp' => [
'transport' => 'smtp',
'host' => env('MAIL_HOST', 'smtp.mailgun.org'),
'port' => env('MAIL_PORT', 587),
'encryption' => env('MAIL_ENCRYPTION', 'tls'),
'username' => env('MAIL_USERNAME'),
'password' => env('MAIL_PASSWORD'),
'timeout' => null,
'local_domain' => env('MAIL_EHLO_DOMAIN'),
],
'ses' => [
'transport' => 'ses',
],
'mailgun' => [
'transport' => 'mailgun',
],
'postmark' => [
'transport' => 'postmark',
],
'sendmail' => [
'transport' => 'sendmail',
'path' => env('MAIL_SENDMAIL_PATH', '/usr/sbin/sendmail -bs -i'),
],
'log' => [
'transport' => 'log',
'channel' => env('MAIL_LOG_CHANNEL'),
],
'array' => [
'transport' => 'array',
],
'failover' => [
'transport' => 'failover',
'mailers' => [
'smtp',
'log',
],
],
],
/*
|--------------------------------------------------------------------------
| Global "From" Address
|--------------------------------------------------------------------------
|
| You may wish for all e-mails sent by your application to be sent from
| the same address. Here, you may specify a name and address that is
| used globally for all e-mails that are sent by your application.
|
*/
'from' => [
'address' => env('MAIL_FROM_ADDRESS', 'hello@example.com'),
'name' => env('MAIL_FROM_NAME', 'Example'),
],
/*
|--------------------------------------------------------------------------
| Markdown Mail Settings
|--------------------------------------------------------------------------
|
| If you are using Markdown based email rendering, you may configure your
| theme and component paths here, allowing you to customize the design
| of the emails. Or, you may simply stick with the Laravel defaults!
|
*/
'markdown' => [
'theme' => 'default',
'paths' => [
resource_path('views/vendor/mail'),
],
],
];
================================================
FILE: submissions/chiconnect-laravel-web-app/config/queue.php
================================================
env('QUEUE_CONNECTION', 'sync'),
/*
|--------------------------------------------------------------------------
| Queue Connections
|--------------------------------------------------------------------------
|
| Here you may configure the connection information for each server that
| is used by your application. A default configuration has been added
| for each back-end shipped with Laravel. You are free to add more.
|
| Drivers: "sync", "database", "beanstalkd", "sqs", "redis", "null"
|
*/
'connections' => [
'sync' => [
'driver' => 'sync',
],
'database' => [
'driver' => 'database',
'table' => 'jobs',
'queue' => 'default',
'retry_after' => 90,
'after_commit' => false,
],
'beanstalkd' => [
'driver' => 'beanstalkd',
'host' => 'localhost',
'queue' => 'default',
'retry_after' => 90,
'block_for' => 0,
'after_commit' => false,
],
'sqs' => [
'driver' => 'sqs',
'key' => env('AWS_ACCESS_KEY_ID'),
'secret' => env('AWS_SECRET_ACCESS_KEY'),
'prefix' => env('SQS_PREFIX', 'https://sqs.us-east-1.amazonaws.com/your-account-id'),
'queue' => env('SQS_QUEUE', 'default'),
'suffix' => env('SQS_SUFFIX'),
'region' => env('AWS_DEFAULT_REGION', 'us-east-1'),
'after_commit' => false,
],
'redis' => [
'driver' => 'redis',
'connection' => 'default',
'queue' => env('REDIS_QUEUE', 'default'),
'retry_after' => 90,
'block_for' => null,
'after_commit' => false,
],
],
/*
|--------------------------------------------------------------------------
| Failed Queue Jobs
|--------------------------------------------------------------------------
|
| These options configure the behavior of failed queue job logging so you
| can control which database and table are used to store the jobs that
| have failed. You may change them to any database / table you wish.
|
*/
'failed' => [
'driver' => env('QUEUE_FAILED_DRIVER', 'database-uuids'),
'database' => env('DB_CONNECTION', 'mysql'),
'table' => 'failed_jobs',
],
];
================================================
FILE: submissions/chiconnect-laravel-web-app/config/sanctum.php
================================================
explode(',', env('SANCTUM_STATEFUL_DOMAINS', sprintf(
'%s%s',
'localhost,localhost:3000,127.0.0.1,127.0.0.1:8000,::1',
Sanctum::currentApplicationUrlWithPort()
))),
/*
|--------------------------------------------------------------------------
| Sanctum Guards
|--------------------------------------------------------------------------
|
| This array contains the authentication guards that will be checked when
| Sanctum is trying to authenticate a request. If none of these guards
| are able to authenticate the request, Sanctum will use the bearer
| token that's present on an incoming request for authentication.
|
*/
'guard' => ['web'],
/*
|--------------------------------------------------------------------------
| Expiration Minutes
|--------------------------------------------------------------------------
|
| This value controls the number of minutes until an issued token will be
| considered expired. If this value is null, personal access tokens do
| not expire. This won't tweak the lifetime of first-party sessions.
|
*/
'expiration' => null,
/*
|--------------------------------------------------------------------------
| Sanctum Middleware
|--------------------------------------------------------------------------
|
| When authenticating your first-party SPA with Sanctum you may need to
| customize some of the middleware Sanctum uses while processing the
| request. You may change the middleware listed below as required.
|
*/
'middleware' => [
'verify_csrf_token' => App\Http\Middleware\VerifyCsrfToken::class,
'encrypt_cookies' => App\Http\Middleware\EncryptCookies::class,
],
];
================================================
FILE: submissions/chiconnect-laravel-web-app/config/services.php
================================================
[
'domain' => env('MAILGUN_DOMAIN'),
'secret' => env('MAILGUN_SECRET'),
'endpoint' => env('MAILGUN_ENDPOINT', 'api.mailgun.net'),
'scheme' => 'https',
],
'postmark' => [
'token' => env('POSTMARK_TOKEN'),
],
'ses' => [
'key' => env('AWS_ACCESS_KEY_ID'),
'secret' => env('AWS_SECRET_ACCESS_KEY'),
'region' => env('AWS_DEFAULT_REGION', 'us-east-1'),
],
];
================================================
FILE: submissions/chiconnect-laravel-web-app/config/session.php
================================================
env('SESSION_DRIVER', 'file'),
/*
|--------------------------------------------------------------------------
| Session Lifetime
|--------------------------------------------------------------------------
|
| Here you may specify the number of minutes that you wish the session
| to be allowed to remain idle before it expires. If you want them
| to immediately expire on the browser closing, set that option.
|
*/
'lifetime' => env('SESSION_LIFETIME', 120),
'expire_on_close' => false,
/*
|--------------------------------------------------------------------------
| Session Encryption
|--------------------------------------------------------------------------
|
| This option allows you to easily specify that all of your session data
| should be encrypted before it is stored. All encryption will be run
| automatically by Laravel and you can use the Session like normal.
|
*/
'encrypt' => false,
/*
|--------------------------------------------------------------------------
| Session File Location
|--------------------------------------------------------------------------
|
| When using the native session driver, we need a location where session
| files may be stored. A default has been set for you but a different
| location may be specified. This is only needed for file sessions.
|
*/
'files' => storage_path('framework/sessions'),
/*
|--------------------------------------------------------------------------
| Session Database Connection
|--------------------------------------------------------------------------
|
| When using the "database" or "redis" session drivers, you may specify a
| connection that should be used to manage these sessions. This should
| correspond to a connection in your database configuration options.
|
*/
'connection' => env('SESSION_CONNECTION'),
/*
|--------------------------------------------------------------------------
| Session Database Table
|--------------------------------------------------------------------------
|
| When using the "database" session driver, you may specify the table we
| should use to manage the sessions. Of course, a sensible default is
| provided for you; however, you are free to change this as needed.
|
*/
'table' => 'sessions',
/*
|--------------------------------------------------------------------------
| Session Cache Store
|--------------------------------------------------------------------------
|
| While using one of the framework's cache driven session backends you may
| list a cache store that should be used for these sessions. This value
| must match with one of the application's configured cache "stores".
|
| Affects: "apc", "dynamodb", "memcached", "redis"
|
*/
'store' => env('SESSION_STORE'),
/*
|--------------------------------------------------------------------------
| Session Sweeping Lottery
|--------------------------------------------------------------------------
|
| Some session drivers must manually sweep their storage location to get
| rid of old sessions from storage. Here are the chances that it will
| happen on a given request. By default, the odds are 2 out of 100.
|
*/
'lottery' => [2, 100],
/*
|--------------------------------------------------------------------------
| Session Cookie Name
|--------------------------------------------------------------------------
|
| Here you may change the name of the cookie used to identify a session
| instance by ID. The name specified here will get used every time a
| new session cookie is created by the framework for every driver.
|
*/
'cookie' => env(
'SESSION_COOKIE',
Str::slug(env('APP_NAME', 'laravel'), '_').'_session'
),
/*
|--------------------------------------------------------------------------
| Session Cookie Path
|--------------------------------------------------------------------------
|
| The session cookie path determines the path for which the cookie will
| be regarded as available. Typically, this will be the root path of
| your application but you are free to change this when necessary.
|
*/
'path' => '/',
/*
|--------------------------------------------------------------------------
| Session Cookie Domain
|--------------------------------------------------------------------------
|
| Here you may change the domain of the cookie used to identify a session
| in your application. This will determine which domains the cookie is
| available to in your application. A sensible default has been set.
|
*/
'domain' => env('SESSION_DOMAIN'),
/*
|--------------------------------------------------------------------------
| HTTPS Only Cookies
|--------------------------------------------------------------------------
|
| By setting this option to true, session cookies will only be sent back
| to the server if the browser has a HTTPS connection. This will keep
| the cookie from being sent to you when it can't be done securely.
|
*/
'secure' => env('SESSION_SECURE_COOKIE'),
/*
|--------------------------------------------------------------------------
| HTTP Access Only
|--------------------------------------------------------------------------
|
| Setting this value to true will prevent JavaScript from accessing the
| value of the cookie and the cookie will only be accessible through
| the HTTP protocol. You are free to modify this option if needed.
|
*/
'http_only' => true,
/*
|--------------------------------------------------------------------------
| Same-Site Cookies
|--------------------------------------------------------------------------
|
| This option determines how your cookies behave when cross-site requests
| take place, and can be used to mitigate CSRF attacks. By default, we
| will set this value to "lax" since this is a secure default value.
|
| Supported: "lax", "strict", "none", null
|
*/
'same_site' => 'lax',
];
================================================
FILE: submissions/chiconnect-laravel-web-app/config/view.php
================================================
[
resource_path('views'),
],
/*
|--------------------------------------------------------------------------
| Compiled View Path
|--------------------------------------------------------------------------
|
| This option determines where all the compiled Blade templates will be
| stored for your application. Typically, this is within the storage
| directory. However, as usual, you are free to change this value.
|
*/
'compiled' => env(
'VIEW_COMPILED_PATH',
realpath(storage_path('framework/views'))
),
];
================================================
FILE: submissions/chiconnect-laravel-web-app/database/.gitignore
================================================
*.sqlite*
================================================
FILE: submissions/chiconnect-laravel-web-app/database/factories/UserFactory.php
================================================
*/
class UserFactory extends Factory
{
/**
* Define the model's default state.
*
* @return array
*/
public function definition()
{
return [
'name' => fake()->name(),
'email' => fake()->unique()->safeEmail(),
'email_verified_at' => now(),
'password' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', // password
'remember_token' => Str::random(10),
];
}
/**
* Indicate that the model's email address should be unverified.
*
* @return static
*/
public function unverified()
{
return $this->state(fn (array $attributes) => [
'email_verified_at' => null,
]);
}
}
================================================
FILE: submissions/chiconnect-laravel-web-app/database/migrations/2014_10_12_000000_create_users_table.php
================================================
id();
$table->uuid('uuid');
$table->string('name');
$table->string('email')->unique();
$table->enum('type', ['customer', 'admin'])->default('customer');
$table->timestamp('email_verified_at')->nullable();
$table->string('sub_account_id')->nullable();
$table->string('password');
$table->rememberToken();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('users');
}
};
================================================
FILE: submissions/chiconnect-laravel-web-app/database/migrations/2014_10_12_100000_create_password_resets_table.php
================================================
string('email')->index();
$table->string('token');
$table->timestamp('created_at')->nullable();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('password_resets');
}
};
================================================
FILE: submissions/chiconnect-laravel-web-app/database/migrations/2019_08_19_000000_create_failed_jobs_table.php
================================================
id();
$table->string('uuid')->unique();
$table->text('connection');
$table->text('queue');
$table->longText('payload');
$table->longText('exception');
$table->timestamp('failed_at')->useCurrent();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('failed_jobs');
}
};
================================================
FILE: submissions/chiconnect-laravel-web-app/database/migrations/2019_12_14_000001_create_personal_access_tokens_table.php
================================================
id();
$table->morphs('tokenable');
$table->string('name');
$table->string('token', 64)->unique();
$table->text('abilities')->nullable();
$table->timestamp('last_used_at')->nullable();
$table->timestamp('expires_at')->nullable();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('personal_access_tokens');
}
};
================================================
FILE: submissions/chiconnect-laravel-web-app/database/migrations/2022_10_17_080103_add_username_to_users_table.php
================================================
string('username')->nullable();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('users', function (Blueprint $table) {
$table->dropColumn('username');
});
}
};
================================================
FILE: submissions/chiconnect-laravel-web-app/database/migrations/2022_10_17_194518_create_transactions_table.php
================================================
id();
$table->string('tnxID');
$table->string('sender');
$table->string('receiver');
$table->string('amount');
$table->string('wallet');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('transactions');
}
};
================================================
FILE: submissions/chiconnect-laravel-web-app/database/migrations/2022_10_20_180113_add_chi_wallet_id_to_users_table.php
================================================
string('chi_wallet_id')->nullable();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('users', function (Blueprint $table) {
$table->dropColumn('chi_wallet_id');
});
}
};
================================================
FILE: submissions/chiconnect-laravel-web-app/database/migrations/2022_10_20_204612_create_payouts_table.php
================================================
id();
$table->string('issuer');
$table->string('chiRef');
$table->enum('type', ['airtime', 'chimoney', 'giftcard', 'momo']);
$table->string('amount')->nullable();
$table->string('recipient')->nullable();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('payouts');
}
};
================================================
FILE: submissions/chiconnect-laravel-web-app/database/migrations/2022_10_22_165728_create_transaction_references_table.php
================================================
id();
$table->string('uuid');
$table->string('chiRef')->nullable();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('transaction_references');
}
};
================================================
FILE: submissions/chiconnect-laravel-web-app/database/migrations/2022_10_22_171931_alter_type_column_in_payouts_table.php
================================================
set_schema_table . " MODIFY COLUMN type ENUM('airtime', 'chimoney', 'giftcard', 'momo', 'bank') NOT NULL");
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
DB::statement("ALTER TABLE " . $this->set_schema_table . " MODIFY COLUMN type ENUM('airtime', 'chimoney', 'giftcard', 'momo') NOT NULL");
}
};
================================================
FILE: submissions/chiconnect-laravel-web-app/database/seeders/DatabaseSeeder.php
================================================
create();
// \App\Models\User::factory()->create([
// 'name' => 'Test User',
// 'email' => 'test@example.com',
// ]);
}
}
================================================
FILE: submissions/chiconnect-laravel-web-app/lang/en/auth.php
================================================
'These credentials do not match our records.',
'password' => 'The provided password is incorrect.',
'throttle' => 'Too many login attempts. Please try again in :seconds seconds.',
];
================================================
FILE: submissions/chiconnect-laravel-web-app/lang/en/pagination.php
================================================
'« Previous',
'next' => 'Next »',
];
================================================
FILE: submissions/chiconnect-laravel-web-app/lang/en/passwords.php
================================================
'Your password has been reset!',
'sent' => 'We have emailed your password reset link!',
'throttled' => 'Please wait before retrying.',
'token' => 'This password reset token is invalid.',
'user' => "We can't find a user with that email address.",
];
================================================
FILE: submissions/chiconnect-laravel-web-app/lang/en/validation.php
================================================
'The :attribute must be accepted.',
'accepted_if' => 'The :attribute must be accepted when :other is :value.',
'active_url' => 'The :attribute is not a valid URL.',
'after' => 'The :attribute must be a date after :date.',
'after_or_equal' => 'The :attribute must be a date after or equal to :date.',
'alpha' => 'The :attribute must only contain letters.',
'alpha_dash' => 'The :attribute must only contain letters, numbers, dashes and underscores.',
'alpha_num' => 'The :attribute must only contain letters and numbers.',
'array' => 'The :attribute must be an array.',
'before' => 'The :attribute must be a date before :date.',
'before_or_equal' => 'The :attribute must be a date before or equal to :date.',
'between' => [
'array' => 'The :attribute must have between :min and :max items.',
'file' => 'The :attribute must be between :min and :max kilobytes.',
'numeric' => 'The :attribute must be between :min and :max.',
'string' => 'The :attribute must be between :min and :max characters.',
],
'boolean' => 'The :attribute field must be true or false.',
'confirmed' => 'The :attribute confirmation does not match.',
'current_password' => 'The password is incorrect.',
'date' => 'The :attribute is not a valid date.',
'date_equals' => 'The :attribute must be a date equal to :date.',
'date_format' => 'The :attribute does not match the format :format.',
'declined' => 'The :attribute must be declined.',
'declined_if' => 'The :attribute must be declined when :other is :value.',
'different' => 'The :attribute and :other must be different.',
'digits' => 'The :attribute must be :digits digits.',
'digits_between' => 'The :attribute must be between :min and :max digits.',
'dimensions' => 'The :attribute has invalid image dimensions.',
'distinct' => 'The :attribute field has a duplicate value.',
'doesnt_end_with' => 'The :attribute may not end with one of the following: :values.',
'doesnt_start_with' => 'The :attribute may not start with one of the following: :values.',
'email' => 'The :attribute must be a valid email address.',
'ends_with' => 'The :attribute must end with one of the following: :values.',
'enum' => 'The selected :attribute is invalid.',
'exists' => 'The selected :attribute is invalid.',
'file' => 'The :attribute must be a file.',
'filled' => 'The :attribute field must have a value.',
'gt' => [
'array' => 'The :attribute must have more than :value items.',
'file' => 'The :attribute must be greater than :value kilobytes.',
'numeric' => 'The :attribute must be greater than :value.',
'string' => 'The :attribute must be greater than :value characters.',
],
'gte' => [
'array' => 'The :attribute must have :value items or more.',
'file' => 'The :attribute must be greater than or equal to :value kilobytes.',
'numeric' => 'The :attribute must be greater than or equal to :value.',
'string' => 'The :attribute must be greater than or equal to :value characters.',
],
'image' => 'The :attribute must be an image.',
'in' => 'The selected :attribute is invalid.',
'in_array' => 'The :attribute field does not exist in :other.',
'integer' => 'The :attribute must be an integer.',
'ip' => 'The :attribute must be a valid IP address.',
'ipv4' => 'The :attribute must be a valid IPv4 address.',
'ipv6' => 'The :attribute must be a valid IPv6 address.',
'json' => 'The :attribute must be a valid JSON string.',
'lt' => [
'array' => 'The :attribute must have less than :value items.',
'file' => 'The :attribute must be less than :value kilobytes.',
'numeric' => 'The :attribute must be less than :value.',
'string' => 'The :attribute must be less than :value characters.',
],
'lte' => [
'array' => 'The :attribute must not have more than :value items.',
'file' => 'The :attribute must be less than or equal to :value kilobytes.',
'numeric' => 'The :attribute must be less than or equal to :value.',
'string' => 'The :attribute must be less than or equal to :value characters.',
],
'mac_address' => 'The :attribute must be a valid MAC address.',
'max' => [
'array' => 'The :attribute must not have more than :max items.',
'file' => 'The :attribute must not be greater than :max kilobytes.',
'numeric' => 'The :attribute must not be greater than :max.',
'string' => 'The :attribute must not be greater than :max characters.',
],
'max_digits' => 'The :attribute must not have more than :max digits.',
'mimes' => 'The :attribute must be a file of type: :values.',
'mimetypes' => 'The :attribute must be a file of type: :values.',
'min' => [
'array' => 'The :attribute must have at least :min items.',
'file' => 'The :attribute must be at least :min kilobytes.',
'numeric' => 'The :attribute must be at least :min.',
'string' => 'The :attribute must be at least :min characters.',
],
'min_digits' => 'The :attribute must have at least :min digits.',
'multiple_of' => 'The :attribute must be a multiple of :value.',
'not_in' => 'The selected :attribute is invalid.',
'not_regex' => 'The :attribute format is invalid.',
'numeric' => 'The :attribute must be a number.',
'password' => [
'letters' => 'The :attribute must contain at least one letter.',
'mixed' => 'The :attribute must contain at least one uppercase and one lowercase letter.',
'numbers' => 'The :attribute must contain at least one number.',
'symbols' => 'The :attribute must contain at least one symbol.',
'uncompromised' => 'The given :attribute has appeared in a data leak. Please choose a different :attribute.',
],
'present' => 'The :attribute field must be present.',
'prohibited' => 'The :attribute field is prohibited.',
'prohibited_if' => 'The :attribute field is prohibited when :other is :value.',
'prohibited_unless' => 'The :attribute field is prohibited unless :other is in :values.',
'prohibits' => 'The :attribute field prohibits :other from being present.',
'regex' => 'The :attribute format is invalid.',
'required' => 'The :attribute field is required.',
'required_array_keys' => 'The :attribute field must contain entries for: :values.',
'required_if' => 'The :attribute field is required when :other is :value.',
'required_if_accepted' => 'The :attribute field is required when :other is accepted.',
'required_unless' => 'The :attribute field is required unless :other is in :values.',
'required_with' => 'The :attribute field is required when :values is present.',
'required_with_all' => 'The :attribute field is required when :values are present.',
'required_without' => 'The :attribute field is required when :values is not present.',
'required_without_all' => 'The :attribute field is required when none of :values are present.',
'same' => 'The :attribute and :other must match.',
'size' => [
'array' => 'The :attribute must contain :size items.',
'file' => 'The :attribute must be :size kilobytes.',
'numeric' => 'The :attribute must be :size.',
'string' => 'The :attribute must be :size characters.',
],
'starts_with' => 'The :attribute must start with one of the following: :values.',
'string' => 'The :attribute must be a string.',
'timezone' => 'The :attribute must be a valid timezone.',
'unique' => 'The :attribute has already been taken.',
'uploaded' => 'The :attribute failed to upload.',
'url' => 'The :attribute must be a valid URL.',
'uuid' => 'The :attribute must be a valid UUID.',
/*
|--------------------------------------------------------------------------
| Custom Validation Language Lines
|--------------------------------------------------------------------------
|
| Here you may specify custom validation messages for attributes using the
| convention "attribute.rule" to name the lines. This makes it quick to
| specify a specific custom language line for a given attribute rule.
|
*/
'custom' => [
'attribute-name' => [
'rule-name' => 'custom-message',
],
],
/*
|--------------------------------------------------------------------------
| Custom Validation Attributes
|--------------------------------------------------------------------------
|
| The following language lines are used to swap our attribute placeholder
| with something more reader friendly such as "E-Mail Address" instead
| of "email". This simply helps us make our message more expressive.
|
*/
'attributes' => [],
];
================================================
FILE: submissions/chiconnect-laravel-web-app/package.json
================================================
{
"private": true,
"scripts": {
"dev": "vite",
"build": "vite build"
},
"devDependencies": {
"@tailwindcss/forms": "^0.5.2",
"alpinejs": "^3.4.2",
"autoprefixer": "^10.4.2",
"axios": "^0.27",
"laravel-vite-plugin": "^0.6.0",
"lodash": "^4.17.19",
"postcss": "^8.4.6",
"tailwindcss": "^3.1.0",
"vite": "^3.0.0"
}
}
================================================
FILE: submissions/chiconnect-laravel-web-app/phpunit.xml
================================================
./tests/Unit./tests/Feature./app
================================================
FILE: submissions/chiconnect-laravel-web-app/postcss.config.js
================================================
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
};
================================================
FILE: submissions/chiconnect-laravel-web-app/public/.htaccess
================================================
Options -MultiViews -Indexes
RewriteEngine On
# Handle Authorization Header
RewriteCond %{HTTP:Authorization} .
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
# Redirect Trailing Slashes If Not A Folder...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} (.+)/$
RewriteRule ^ %1 [L,R=301]
# Send Requests To Front Controller...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
================================================
FILE: submissions/chiconnect-laravel-web-app/public/index.php
================================================
make(Kernel::class);
$response = $kernel->handle(
$request = Request::capture()
)->send();
$kernel->terminate($request, $response);
================================================
FILE: submissions/chiconnect-laravel-web-app/public/robots.txt
================================================
User-agent: *
Disallow:
================================================
FILE: submissions/chiconnect-laravel-web-app/resources/css/app.css
================================================
@tailwind base;
@tailwind components;
@tailwind utilities;
================================================
FILE: submissions/chiconnect-laravel-web-app/resources/js/app.js
================================================
import './bootstrap';
import Alpine from 'alpinejs';
window.Alpine = Alpine;
Alpine.start();
================================================
FILE: submissions/chiconnect-laravel-web-app/resources/js/bootstrap.js
================================================
import _ from 'lodash';
window._ = _;
/**
* We'll load the axios HTTP library which allows us to easily issue requests
* to our Laravel back-end. This library automatically handles sending the
* CSRF token as a header based on the value of the "XSRF" token cookie.
*/
import axios from 'axios';
window.axios = axios;
window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
/**
* Echo exposes an expressive API for subscribing to channels and listening
* for events that are broadcast by Laravel. Echo and event broadcasting
* allows your team to easily build robust real-time web applications.
*/
// import Echo from 'laravel-echo';
// import Pusher from 'pusher-js';
// window.Pusher = Pusher;
// window.Echo = new Echo({
// broadcaster: 'pusher',
// key: import.meta.env.VITE_PUSHER_APP_KEY,
// wsHost: import.meta.env.VITE_PUSHER_HOST ?? `ws-${import.meta.env.VITE_PUSHER_APP_CLUSTER}.pusher.com`,
// wsPort: import.meta.env.VITE_PUSHER_PORT ?? 80,
// wssPort: import.meta.env.VITE_PUSHER_PORT ?? 443,
// forceTLS: (import.meta.env.VITE_PUSHER_SCHEME ?? 'https') === 'https',
// enabledTransports: ['ws', 'wss'],
// });
================================================
FILE: submissions/chiconnect-laravel-web-app/resources/views/account/topup-user.blade.php
================================================
{{ __('Forgot your password? No problem. Just let us know your email address and we will email you a password reset link that will allow you to choose a new one.') }}
{{ __('Thanks for signing up! Before getting started, could you verify your email address by clicking on the link we just emailed to you? If you didn\'t receive the email, we will gladly send you another.') }}
Laravel has wonderful, thorough documentation covering every aspect of the framework. Whether you are new to the framework or have previous experience with Laravel, we recommend reading all of the documentation from beginning to end.
Laracasts offers thousands of video tutorials on Laravel, PHP, and JavaScript development. Check them out, see for yourself, and massively level up your development skills in the process.
Laravel News is a community driven portal and newsletter aggregating all of the latest and most important news in the Laravel ecosystem, including new package releases and tutorials.
Vibrant Ecosystem
Laravel's robust library of first-party tools and libraries, such as Forge, Vapor, Nova, and Envoyer help you take your projects to the next level. Pair them with powerful open source libraries like Cashier, Dusk, Echo, Horizon, Sanctum, Telescope, and more.