PayMongo Integration - Full CodeIgniter 4 Files
1■■ Migration File:
app/Database/Migrations/[Link]
<?php
namespace App\Database\Migrations;
use CodeIgniter\Database\Migration;
class CreatePaymentsTable extends Migration
{
public function up()
{
$this->forge->addField([
'id' => ['type' => 'INT', 'constraint' => 11, 'unsigned' => true, 'auto_increment' => tru
'order_id' => ['type' => 'VARCHAR', 'constraint' => 100],
'paymongo_id' => ['type' => 'VARCHAR', 'constraint' => 100, 'null' => true],
'amount' => ['type' => 'INT', 'null' => false],
'currency' => ['type' => 'VARCHAR', 'constraint' => 10, 'default' => 'PHP'],
'status' => ['type' => 'VARCHAR', 'constraint' => 30, 'default' => 'pending'],
'payload' => ['type' => 'JSON', 'null' => true],
'created_at' => ['type' => 'DATETIME', 'null' => true],
'updated_at' => ['type' => 'DATETIME', 'null' => true]
]);
$this->forge->addKey('id', true);
$this->forge->createTable('payments');
}
public function down()
{
$this->forge->dropTable('payments');
}
}
2■■ Model File: app/Models/[Link]
<?php
namespace App\Models;
use CodeIgniter\Model;
class PaymentModel extends Model
{
protected $table = 'payments';
protected $primaryKey = 'id';
protected $allowedFields = [
'order_id', 'paymongo_id', 'amount', 'currency', 'status', 'payload', 'created_at', 'updated_
];
}
3■■ Controller File: app/Controllers/[Link]
<?php
namespace App\Controllers;
use CodeIgniter\Controller;
use App\Models\PaymentModel;
class PaymongoController extends Controller
{
protected $secretKey;
protected $webhookSecret;
public function __construct()
{
$this->secretKey = getenv('PAYMONGO_SECRET');
$this->webhookSecret = getenv('PAYMONGO_WEBHOOK_SECRET');
}
public function create()
{
$model = new PaymentModel();
$post = $this->request->getPost();
$amount = (int)$post['amount'];
$orderId = $post['order_id'];
$model->insert([
'order_id' => $orderId,
'amount' => $amount,
'status' => 'pending'
]);
$payload = [
'data' => [
'attributes' => [
'amount' => $amount,
'currency' => 'PHP',
'billing' => ['name' => $post['name'] ?? 'Customer'],
'redirect' => [
'success' => base_url('paymongo/return?status=success'),
'failed' => base_url('paymongo/return?status=failed')
]
]
]
];
$ch = curl_init('[Link]
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_USERPWD => $this->secretKey . ':',
CURLOPT_POSTFIELDS => json_encode($payload),
CURLOPT_HTTPHEADER => ['Content-Type: application/json']
]);
$res = curl_exec($ch);
$http = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($http >= 200 && $http < 300) {
$resp = json_decode($res, true);
$url = $resp['data']['attributes']['checkout_url'] ?? null;
return redirect()->to($url);
} else {
return $this->response->setStatusCode(500)->setJSON(['error' => 'Failed to create session
}
}
public function webhook()
{
$model = new PaymentModel();
$payload = $this->request->getBody();
$header = $this->request->getHeaderLine('Paymongo-Signature');
if (!$this->verifySignature($header, $payload, $this->webhookSecret)) {
return $this->response->setStatusCode(400)->setJSON(['error'=>'Invalid signature']);
}
$event = json_decode($payload, true);
$type = $event['type'] ?? '';
if ($type === '[Link]' || $type === '[Link]') {
$data = $event['data'];
$paymongoId = $data['id'] ?? null;
$model->where('paymongo_id', $paymongoId)->set(['status' => 'paid', 'payload' => $payload
}
return $this->response->setStatusCode(200)->setJSON(['received'=>true]);
}
private function verifySignature($header, $payload, $secret)
{
if (!$header) return false;
$parts = explode(',', $header);
$map = [];
foreach ($parts as $p) {
[$k,$v] = explode('=', $p, 2) + [null,null];
$map[$k] = $v;
}
$timestamp = $map['t'] ?? '';
$sig_test = $map['te'] ?? '';
$sig_live = $map['li'] ?? '';
$computed = hash_hmac('sha256', $timestamp . $payload, $secret);
if (!empty($sig_test)) return hash_equals($sig_test, $computed);
if (!empty($sig_live)) return hash_equals($sig_live, $computed);
return false;
}
public function success()
{
echo "Payment completed successfully.";
}
}
4■■ View File: app/Views/paymongo_form.php
<form action="/paymongo/create" method="post">
<input type="hidden" name="order_id" value="ORD-001">
<label>Amount (PHP):</label>
<input name="amount_display" type="number" value="100.00" step="0.01" />
<input type="hidden" name="amount" value="10000" />
<input name="name" value="Juan dela Cruz" />
<button type="submit">Pay with PayMongo</button>
</form>