M-Pesa C2B APIの解説ページを参考に、動作の雰囲気をつかむ

# 背景

M-Pesaの[公式サイトの開発者向けページ](https://developer.safaricom.co.ke/) には、認証やコマンドID、API仕様書があります。開発を進めるには便利ですが、最初の一歩としては敷居が高いです。
そこで、ケニアの技術者の方が書いた下記の解説ページを見ながら、C2BのAPIを呼び出してトランザクションの生成をして、どんなデータが送信されるか確認します。

- [How to Develop Mpesa Integration to Website Using Safaricom C2B API](https://www.tekfansworld.com/how-to-develop-mpesa-integration-to-website-using-c2b-api.html)


# 環境
- レンタルサーバ
    - PHP 7.3
    - MySQL 5.7
    - 公開できるページ(外部からコールバックでphpを呼び出されるので)
        - SSL(https接続が必要)
        - .htaccessファイル (必要に応じて、外部からアクセスできるように設定)

# テスト用のshortcodeとcredentialsの取得

- Initiator用のパスワード(最大20文字)を決めておく
- [開発者サイト](https://developer.safaricom.co.ke/)にログイン
- [Test Credentials 生成ページ](https://developer.safaricom.co.ke/test_credentials)を開く
- 「`Shortcode 1`」が表示されるので、メモしておく
    - 有効期間は3日間です
    - たまに`Shortcode 1`も`Shortcode 2`も空欄になってしまう場合があります。その場合は、「`Initiator Security Password`」を **入れずに** Refreshボタンを押すと、表示される場合があります。
- 下の方の「`Initiator Security Password For? *`」で「`Test`」を選び、`Initiator用のパスワード`を入れて「`Generae Credentrials`」をクリック
- 「`Generated Initiator Security Credential:`」の下に、クレデンシャルが表示されるので、保存しておく


![02_1_test_credential.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142577/1637d6fd-41de-2cb3-f73b-94ac998785e6.png)





# DBにテーブルを作成

```
CREATE TABLE mpesa_payments (
  id INT AUTO_INCREMENT NOT NULL PRIMARY KEY,
  Auto double,
  TransactionType VARCHAR(40),
  TransID  VARCHAR(40),
  TransTime VARCHAR(40),
  TransAmount double,
  BusinessShortCode VARCHAR(15),
  BillRefNumber VARCHAR(40),
  InvoiceNumber VARCHAR(40),
  ThirdPartyTransID VARCHAR(40),
  MSISDN VARCHAR(20),
  FirstName VARCHAR(60),
  MiddleName VARCHAR(60),
  LastName VARCHAR(60),
  OrgAccountBalance double
) DEFAULT CHARSET= utf8mb4
;
```

# validation用とconfirmation用のURLとサーバを用意する

- レンタルサーバなどで、httpsで外部からアクセスできるように設定する。(Let's Encryptとか)
    - URL(ディレクトリ名など)に「mpesa」が入っていると後述のURL登録で失敗するので、mpsとかにしておく


# 解説ページにある2つのファイルを配置

- validation.php を配置する(解説ページの「Step 6:  Creating a C2B validation Callback URL」)
    - そのままアップロードする
    - WEBブラウザからファイルにアクセスすると、「`Technical error`」と表示されればOK。
        - 例： https://www.example.com/mps/validation.php
- confirmation.php を配置する(解説ページの「Step 7:  Creating a C2B Confirmation Callback URL on Your Website」)
    - アクセス用パスワードを決めておき、8行目付近の`'yourPU_RstrongPasswordSample$'`の部分を置換して入れる
    - 19-22行目付近の、`$servername`, `$username`, `$password`, `$dbname` にデータベースのサーバ名などを設定する
    - ファイルをアップロードする
    - WEBブラウザからファイルにアクセスすると、「`Technical error`」と表示されればOK。
        - 例： https://www.example.com/mps/confirmation.php


# M-pesa payment gatewayにコールバックURLを登録するためのファイルを設置する

- register.php を配置する(解説ページの「Step 8:  Registering Validation and Confirmation Callback URLs on Safaricom API」)
- [MY APPS](https://developer.safaricom.co.ke/user/me/apps)のページで、`Consumer Key`と`Consumer Secret`をメモしておく
- `$shortcode`, `$consumerkey`, `$consumersecret` にパスワードなどを設定する
- `$validationurl`, `$confirmationurl` に上記で配置したファイルのURLを設定。
    - (`https://www.example.com/mps/validation.php?token='yourPU_RstrongPasswordSample$'`
のようになる。解説ページにあるサンプルはパスワードが微妙に違うので注意。)


# コールバックURLを呼び出して、URLを登録する

- WEBブラウザで、上記で設置したregister.phpを開くと、中でcurlが動いて、URLが登録される
    - 例： https://www.example.com/mps/register.php
    - 「`"ResponseDescription": "success"`」が返ってくれば成功

```
{
            "ConversationID": "",
            "OriginatorCoversationID": "",
            "ResponseDescription": "success"
        }
```

- URLに「mpesa」が入っていると、以下のようにエラーになる

```
{
                    "requestId":"28813-6618036-1",
                    "errorCode": "400.003.02",
                    "errorMessage": "Bad Request - Invalid ValidationURL - URL has the word MPESA"
}
```


# 「Mpesa API URLs simulator」で、擬似トランザクションを流して、動作確認する

- [Mpesa API URLs simulator](https://www.tekfansworld.com/simulate/mpesa-c2b-api-simulation.php) を開く

- `Validation URL`、`Confirmation URL` を入力して、「`Send Sample Transaction`」ボタンを押す
    - URLには、「`?token=yourPU_RstrongPasswordSample$`」と、トークン文字列も入れる

- 画面の下部に、以下のように表示されればOK。
    - 判定処理が入っていないため、「`Validation URL said :`」が「`Failed`」と「`Success`」の2つ表示されますが、DBには値が入ります。
        - 「`You don't have permission to access this resource.`」のように表示された場合は、.htaccessなどでアクセス制限を解除する必要があるかもしれません。

<img width="1227" alt="02_2_APITestingResults.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142577/76f61a54-9951-0c66-b433-9c27a2b96a9d.png">

```
Mpesa PHP API Testing Results
Sample data sent :

{ "TransactionType": "Pay Bill", "TransID": "LUG8366JGC", "TransTime": "20200210093951", "TransAmount": "0.06", "BusinessShortCode": "999999", "BillRefNumber": "SAMPLE ACCOUNT 101", "InvoiceNumber": "", "OrgAccountBalance": "0.06", "ThirdPartyTransID": "", "MSISDN": "254000000000", "FirstName": "JOHN", "MiddleName": "M.", "LastName": "DOE" }

Validation URL said :

{"ResultCode":1, "ResultDesc":"Failed", "ThirdPartyTransID": 0}{"ResultCode":0, "ResultDesc":"Success", "ThirdPartyTransID": 0}

Confirmation URL said :

{"ResultCode":0,"ResultDesc":"Confirmation received successfully"}
```



- DBも確認する。2レコード入ればOK。
    - TransTime列に実行した時刻、TransIDにトランザクションIDが入る
        - ケニアはUTC+3なので、実行した時刻は日本時間(UTC+9)より6時間前の時刻が入る