ekolotech / mobilemoney-gateway

提供一套可用于调用非洲移动货币支付API和Web界面的类

1.2.2 2024-04-19 17:31 UTC

This package is auto-updated.

Last update: 2024-09-19 18:24:33 UTC


README

作者: @igorcyberdyne@EKOLOTECH

ekolotech/mobilemoney-gateway 是一个组件,提供了一组类和方法,允许使用移动货币支付操作的API和存款API,用于操作员和支付平台。

支持的运营商和平台

  • MTN Mobile Money

如何安装?

您可以从以下位置下载组件:

github ekolotech/mobilemoney-gateway

或者在控制台执行以下命令:

composer require ekolotech/mobilemoney-gateway

------------------------------------- 应用场景 -------------------------------------

I - MTN Mobile Money API (MoMo API)

在此级别,组件实现了MoMo API的两个产品;即Collections产品和Disbursements产品。

为了对这两个产品进行操作,两个具有CollectionGatewayInterfaceDisbursementGatewayInterface签名的对象分别允许使用收款或现金收集操作和付款或存款操作。

1. CollectionGatewayInterface

interface CollectionGatewayInterface
{
    public function collect(CollectRequestBody $collectRequestBody): bool;
    public function collectReference(string $reference): array;
    public function balance(): array;
    public function isAccountIsActive(string $number): bool;
    public function getAccountBasicInfo(string $number): array;
}
class CollectRequestBody
{
    public function __construct(
        public readonly int    $amount, // Le montant
        public readonly string $number, // le numéro MoMo du client
        public readonly string $reference, // la référence de la transaction. Il doit être en version 4 du UUID
    )
    {
    }
}

CollectionGatewayInterface接口方法描述

  • collect(...) 允许向客户请求付款。付款请求将在客户授权或拒绝交易,或系统在等待时间超过后中断之前处于待处理状态。使用以下方法检查付款请求状态至关重要。
  • collectReference(...) 允许获取付款请求的状态。

2. DisbursementGatewayInterface

interface DisbursementGatewayInterface
{
    public function disburse(DisburseRequestBody $disburseRequestBody) : bool;
    public function disburseReference(string $reference) : array;
    public function balance() : array;
    public function isAccountIsActive(string $number) : bool;
    public function getAccountBasicInfo(string $number) : array;
}
class DisburseRequestBody
{
    public function __construct(
        public readonly int    $amount, // Le montant
        public readonly string $number, // le numéro MoMo du bénéficiaire
        public readonly string $reference, // la référence de la transaction. Il doit être en version 4 du UUID
    )
    {
    }
}

DisbursementGatewayInterface接口方法描述

  • disburse(...) 允许将您自己的账户中的金额转账到受益人账户。使用以下方法检查转账状态至关重要。
  • disburseReference(...) 允许获取转账状态

对于两个接口

  • isAccountIsActive(...) 允许检查账户持有人是否已在系统中注册并处于活动状态。
  • getAccountBasicInfo(...) 允许获取账户持有人的个人信息,例如姓名和姓氏。
  • balance() 允许获取CollectionsDisbursements的账户余额

3. 如何创建CollectionGatewayInterfaceDisbursementGatewayInterface的实例?

这些两个对象是通过组件的ApiGatewayFactory工厂获得的。

/** 
 * @var CollectionGatewayInterface $collectionGateway 
 */
$collectionGateway = ApiGatewayFactory::loadMtnCollectionGateway(...);

/**
 * @var DisbursementGatewayInterface $disbursementGateway 
 */
$disbursementGateway = ApiGatewayFactory::loadMtnDisbursementGateway(...);

工厂的静态方法需要一个MtnApiAccessAndEnvironmentConfigInterface接口的实例作为参数。此接口允许提供用于与MoMo API沙盒或生产环境服务器通信的配置数据。

interface MtnApiAccessAndEnvironmentConfigInterface
{
    /** Methodes de configuration de l'environnement **/
    public function getBaseApiUrl(): string; // l'url de base de MTN MoMo API. Cette url varie selon l'environnement de sandbox ou de production
    public function isProd(): bool; // définition si le sandbox ou production. false pour le sandbox
    public function getCurrency(): string; // la devise de l'environnement, en €(EURO) pour le sandbox
    public function getProviderCallbackUrl(): string; // Votre end-point de callback. Exemple : https://mon-application.com/callback
    public function getProviderCallbackHost(): string; // Votre host de callback. Exemple : mon-application.com
    
    /** Methodes événementiel à écouter. Il est indispensable d'enregistrer ces données dans une base **/
    public function onApiUserCreated(string $apiUser): void; // Fournit le API User créé
    public function onApiKeyCreated(string $apiKey): void; // Fournit le API key
    public function onTokenCreated(MtnAccessToken $mtnAccessToken): void; // Fournit le token d'accès
    
    /** Methodes de configuration des données d'authentification MoMo API **/
    public function getMtnAuthenticationProduct() : MtnAuthenticationProduct; // Renvoie les clés d'authentification au produit (Collection ou Disbursement)
    public function getMtnAccessToken(): ?MtnAccessToken; // Renvoie le token d'accès
}
  • getProviderCallbackUrl(...) 此 URL 对于生产环境至关重要,因为 MoMo API 服务器会将包含支付交易状态的数发送到此端点。发送到此端点的请求将使用 POST 方法。

MtnAuthenticationProduct(...) 构造函数参数描述

class MtnAuthenticationProduct
{
    public function __construct(
        private readonly string $subscriptionKeyOne,
        private readonly string $subscriptionKeyTwo,
        private ?string         $apiUser = null,
        private ?string         $apiKey = null
    )
    {
    }
}
  • $subscriptionKeyOne '主密钥',需从您的 MoMo API CollectionsDisbursements 个人资料中获取。
  • $subscriptionKeyTwo '辅助密钥',需从您的 MoMo API CollectionsDisbursements 个人资料中获取。
  • $apiUser 如果未提供,将由组件创建。最好实现方法 onApiUserCreated(string $apiUser): void; 以将此值记录到您的数据库中。
  • $apiKey 如果未提供,将由组件创建。最好实现方法 onApiKeyCreated(string $apiKey): void; 以将此值记录到您的数据库中。

MtnAccessToken(...) 构造函数参数描述

此对象允许您执行某些操作。您必须提供此对象,如果没有,它将被生成。实现方法 onTokenCreated(MtnAccessToken $mtnAccessToken): void 以将其记录到您的数据库中。

class MtnAccessToken
{
    public function __construct(
        private readonly string $accessToken,
        private readonly string $tokenType,
        private readonly int    $expiresIn,
        private readonly bool   $isExpired = false,
    )
    {
    }
}
  • $accessToken 允许您执行 MoMo 支付和存取的访问令牌
  • $tokenType 令牌的类型 access_token
  • $expiresIn access_token 令牌的过期时间,以秒为单位。此时间为 3600 秒,即 1 小时
  • $isExpired 您必须根据创建日期和过期时间来计算,以确定此 access_token 令牌是否已过期。

注意:正确处理参数 $isExpired 对于避免组件重复创建至关重要。

实现示例

class CollectionGatewayServiceImpl implements MtnApiAccessAndEnvironmentConfigInterface 
{
    public function getBaseApiUrl(): string
    {
        return "https://sandbox.momodeveloper.mtn.com";
    }

    public function getProviderCallbackUrl(): string
    {
        return "https://sandbox.momodeveloper.mtn.com";
    }

    public function getProviderCallbackHost(): string
    {
        return "sandbox.momodeveloper.mtn.com";
    }

    public function isProd(): bool
    {
        return false;
    }

    public function getCurrency(): string
    {
        return Currency::EUR;
    }

    public function onApiUserCreated(string $apiUser): void
    {
        // TODO something such as save $apiUser in database
    }

    public function onApiKeyCreated(string $apiKey): void
    {
        // TODO something such as save $apiKey in database
    }

    public function onTokenCreated(MtnAccessToken $mtnAccessToken): void
    {
        // TODO something such as save $mtnAccessToken in database
    }
}
/** @var CollectionGatewayInterface $collectionGateway */
$collectionGateway = ApiGatewayFactory::loadMtnCollectionGateway(
    new CollectionGatewayServiceImpl()
);

$clientNumber = "066304925";
$collectReference = "a103dbea-d5f7-45f3-b2e5-e495904d44cb";

// Vérification si le numéro est enregistré et possède un compte mobile money
if (!$collectionGateway->isAccountIsActive($clientNumber)) {
    die("Le titulaire du compte n'a pas de compte MoMo enregistré");
}

// Données personnelles du client. Peut être utilisé pour confirmer le nom et prénom du client
$personalData = $collectionGateway->getAccountBasicInfo($clientNumber);

// Demande de paiement au client. En production une notification sera envoyé au client pour valider le paiement.
// Une fois le paiement valider par le client, le serveur MoMo API envoie le statut de la transaction sur votre end-point ou URL de callback
if (!$collectionGateway->collect(new CollectRequestBody(150, $clientNumber, $reference))) {
    die("Echec de la demande de paiement");
}

// Vérification du statut de la demande de paiement.
$referenceData = $collectionGateway->collectReference($collectReference);

// Solde du compte de paiement
$balance = $collectionGateway->balance();

演示应用

要查看更完整的示例,请参阅 项目 MobileMoneyGateway > DemoApp 中的演示。您还可以使用以下命令直接从项目根目录运行演示。

php DemoApp\DemoApp.php

注意

由于多个请求同时执行,测试或演示应用的执行可能会失败或被阻塞。通常,当所有测试同时执行时,对账户余额的测试可能会使测试失败。最好以独立于其他测试的方式在演示应用中单独运行测试或方法。