Shopier Ödeme Yöntemini Sanal Pos Olarak Kullanma (3 Viewers)

Mehmet Maşa

Yönetici
Yönetici
5 Tem 2019
52
13
8
İzmir
mehmetmasa.com.tr
#1
Merhaba arkadaşlar, bu gün
Bu linki görmek için izniniz yok Giriş yap veya üye ol.
ödeme yöntemini nasıl sanal pos olarak sitemize entegre edebiliriz onu anlatacağım. Bildiğiniz gibi shopier özel yazılımlar için Api dökümantasyonu ve verdiğiniz siparişin geri dönüşünü alıp kullanmanız için destek sağlamıyor. Bu gün shopier’ın Wocommerce gibi yazılımlar için yaptıkları modülleri kendi yazılımlarımız için yapmamız gerekiyor. Bu gün size güzel bir modül verip nasıl entegre edebileceğinizi anlatacağım 🙂

Shopier Modül Kodları:

PHP:
<?php
class Shopier
{
    private $payment_url = 'https://www.shopier.com/ShowProduct/api_pay4.php';
    private
        $api_key,
        $api_secret,
        $module_version,
        $buyer = [],
        $currency = 'TRY';
    public function __construct($api_key, $api_secret, $module_version = ('1.0.4'))
    {
        $this->api_key = $api_key;
        $this->api_secret = $api_secret;
        $this->module_version = $module_version;
    }
    public function setBuyer(array $fields = [])
    {
        $this->buyerValidateAndLoad($this->buyerFields(), $fields);
    }
    public function setOrderBilling(array $fields = [])
    {
        $this->buyerValidateAndLoad($this->orderBillingFields(), $fields);
    }
    public function setOrderShipping(array $fields = [])
    {
        $this->buyerValidateAndLoad($this->orderShippingFields(), $fields);
    }
    private function buyerValidateAndLoad($validationFields, $fields)
    {
        $diff = array_diff_key($validationFields, $fields);
        if (count($diff) > 0)
            throw new Exception(implode(',', array_keys($diff)) . ' fields are required');
        foreach ($validationFields as $key => $buyerField) {
            $this->buyer[$key] = $fields[$key];
        }
    }
    public function generateFormObject($order_id, $order_total, $callback_url)
    {
        $diff = array_diff_key($this->buyerFields(), $this->buyer);
        if (count($diff) > 0)
            throw new Exception(implode(',', array_keys($diff)) . ' fields are required use "setBuyer()" method ');
        $diff = array_diff_key($this->orderBillingFields(), $this->buyer);
        if (count($diff) > 0)
            throw new Exception(implode(',', array_keys($diff)) . ' fields are required use "setOrderBilling()" method ');
        $diff = array_diff_key($this->orderShippingFields(), $this->buyer);
        if (count($diff) > 0)
            throw new Exception(implode(',', array_keys($diff)) . ' fields are required use "setOrderShipping()" method ');
        $args = array(
            'API_key' => $this->api_key,
            'website_index' => 1,
            'platform_order_id' => $order_id,
            'product_name' => '',
            'product_type' => 0, //1 : downloadable-virtual 0:real object,2:default
            'buyer_name' => $this->buyer['first_name'],
            'buyer_surname' => $this->buyer['last_name'],
            'buyer_email' => $this->buyer['email'],
            'buyer_account_age' => 0,
            'buyer_id_nr' => $this->buyer['id'],
            'buyer_phone' => $this->buyer['phone'],
            'billing_address' => $this->buyer['billing_address'],
            'billing_city' => $this->buyer['billing_city'],
            'billing_country' => $this->buyer['billing_country'],
            'billing_postcode' => $this->buyer['billing_postcode'],
            'shipping_address' => $this->buyer['shipping_address'],
            'shipping_city' => $this->buyer['shipping_city'],
            'shipping_country' => $this->buyer['shipping_country'],
            'shipping_postcode' => $this->buyer['shipping_postcode'],
            'total_order_value' => $order_total,
            'currency' => $this->getCurrency(),
            'platform' => 0,
            'is_in_frame' => 0,
            'current_language' => $this->lang(),
            'modul_version' => $this->module_version,
            'random_nr' => rand(100000, 999999)
        );
        $data = $args["random_nr"] . $args["platform_order_id"] . $args["total_order_value"] . $args["currency"];
        $signature = hash_hmac('sha256', $data, $this->api_secret, true);
        $signature = base64_encode($signature);
        $args['signature'] = $signature;
        $args['callback'] = $callback_url;
        return [
            'elements' => [
                [
                    'tag' => 'form',
                    'attributes' => [
                        'id' => 'shopier_form_special',
                        'method' => 'post',
                        'action' => $this->payment_url
                    ],
                    'children' => array_map(function ($key, $value) {
                        return [
                            'tag' => 'input',
                            'attributes' => [
                                'name' => $key,
                                'value' => $value,
                                'type' => 'hidden',
                            ]
                        ];
                    }, array_keys($args), array_values($args))
                ]
            ]
        ];
    }
    public function generateForm($order_id, $order_total, $callback_url)
    {
        $obj = $this->generateFormObject($order_id, $order_total, $callback_url);
        return $this->recursiveHtmlStringGenerator($obj['elements']);
    }
    public function run($order_id, $order_total, $callback_url)
    {
        $form = $this->generateForm($order_id, $order_total, $callback_url);
        return '<!doctype html>
             <html lang="en">
            <head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title></title>
     </head>
' . $form . '
    <body>
        <script type="text/javascript">
                    document.getElementById("shopier_form_special").submit();
        </script>
     </body>
    </html>
     ';
    }
    // generateFormObject() sınıfının verdiği formattaki arrayden structure çıkartan yapıdırı.
    private function recursiveHtmlStringGenerator(array $elements = [], $string = null)
    {
        foreach ($elements as $element) {
            $attributes = $element['attributes'] ?? [];
            $attributes = array_map(function ($key, $value) {
                return $key . '="' . $value . '"';
            }, array_keys($attributes), array_values($attributes));
            $attribute_string = implode(' ', $attributes);
            $html_in = $element['source'] ?? null;
            $string .= "<{$element['tag']} {$attribute_string} > " . $html_in;
            if (isset($element['children']) && is_array($element['children']))
                $string = $this->recursiveHtmlStringGenerator($element['children'], $string);
            $string .= "</{$element['tag']}>";
        }
        return $string;
    }
    //shopierden gelen dataları kontrol eder.
    public function verifyShopierSignature($post_data)
    {
        if (isset($post_data['platform_order_id'])) {
            $order_id = $post_data['platform_order_id'];
            $random_nr = $post_data['random_nr'];
            if ($order_id != '') {
                $signature = base64_decode($_POST["signature"]);
                $expected = hash_hmac('sha256', $random_nr . $order_id, $this->api_secret, true);
                if ($signature == $expected)
                    return true;
            }
        }
        return false;
    }
    private function buyerFields()
    {
        return [
            'id' => true,
            'first_name' => true,
            'last_name' => true,
            'email' => true,
            'phone' => true,
        ];
    }
    private function orderBillingFields()
    {
        return [
            'billing_address' => true,
            'billing_city' => true,
            'billing_country' => true,
            'billing_postcode' => true,
        ];
    }
    private function orderShippingFields()
    {
        return [
            'shipping_address' => true,
            'shipping_city' => true,
            'shipping_country' => true,
            'shipping_postcode' => true,
        ];
    }
    private function getCurrency()
    {
        $currencyList = [
            'TRY' => 0,
            'USD' => 1,
            'EUR' => 2,
        ];
        return $currencyList[strtoupper($this->currency)] ?? 0;
    }
    private function lang()
    {
        $current_language = "tr-TR";
        $current_lan = 1;
        if ($current_language == "tr-TR") {
            $current_lan = 0;
        }
        return $current_lan;
    }
}
Yukarıdaki verdiğim kodu Shopier.php adında bir dosya içerisine yapıştırın ve kaydedin.

Ödeme miktarı, satın alan kullanıcı hakkında bilgileri alabileceğiniz bir form oluşturun. Ben sadece ödeme miktarını alabileceğim bir form oluşturacağım.
HTML:
<div class="content">
    <div class="container-fluid">
        <div class="row">
            <div class="col-lg-6 col-md-12">
                <div class="card">
                    <div class="content">
                        <form method="post" action="yonlendirme.php">
                            <div class="row">
                                <div>
                                    <div class="form-group col-lg-12 col-md-12 ">
                                        <label>Ödeme Yöntemi</label>
                                        <select class="form-group col-lg-12 col-md-12 ">
                                            <option>Shopier</option>
                                        </select>
                                    </div>
                                </div>
                                <div>
                                    <div class="form-group col-lg-12 col-md-12 ">
                                        <label for="exampleInputEmail1"> Miktar ( Küsüratlı ödeme için . (nokta) kullanın)</label>
                                        <input type="text" name="tutar"
                                               class="form-control border-input"
                                               placeholder="Miktarı Giriniz">
                                    </div>
                                </div>
                            </div>
                            <div class="text-left">
                                <button type="submit" class="btn btn-info btn-fill btn-wd">Bakiye
                                    Yükle
                                </button>
                            </div>
                            <div class="clearfix"></div>
                        </form>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>

Üstteki form’da action bölümünü düzenleyin. Ben örnek olarak yonlendirme.php olarak başka bir dosyaya yönlendireceğim.
Yönlendirme yaptığım dosyaya shopier.php dosyasını dahil edeceğim.
Örnek olduğu için gelen verilerin kontrolünü, güvenlık açıklarını es geçiyorum siz kendiniz kontrol etmelisiniz.


Oluşturduğunuz yonlendirme.php dosyasını açın ve içerisine bunları yapıştırın.


PHP:
if($_POST) {
    $userID = $_SESSION['Id']; // VERİ TABANINA EKLETECEĞİM KULLANICI ID
    date_default_timezone_set('Europe/Istanbul');
    $tutar = strip_tags($_POST["tutar"]);
    if ($tutar == "" || !is_numeric($tutar)) {
        echo '<script>swal("Bilgi", "Tutar Alanı Boş olamaz.", "info") </script>';
    } elseif ($tutar < 1 ) {
        echo '<script>swal("Bilgi", "Minimum ödeme tutarı 10TL.", "info") </script>';
    } else {


        include "shopier.php"; // SHOPİER APİ DAHİL EDİLDİ


        $shopier = new Shopier(API_KEY, API_SECRET);
        $callback_url = "https://mehmetmasa.com.tr"; // Geri Dönüş URL'si


        // ÖDEME YAPAN KİŞİNİN BİLGİLERİ
        $shopier->setBuyer([
            'id' => 23,
            'first_name' => 'Ad', 'last_name' => 'SoyAd', 'email' => 'Mail Adresi', 'phone' => 'Telefon Numarası']);
        // VERİLEN SİPARİŞİN FATURASI
        $shopier->setOrderBilling([
            'billing_address' => 'ADRES - MAHALLE',
            'billing_city' => 'ŞEHİR',
            'billing_country' => 'ÜLKE',
            'billing_postcode' => 'POSTA KODU',
        ]);
        // SİPARİŞİ VEREN KİŞİ - ÜSTTEKİ İLE AYNI BİLGİLERİ GİREBİLİRSİNİZ.
        $shopier->setOrderShipping([
            'shipping_address' => 'ADRES - MAHALLE',
            'shipping_city' => 'ŞEHİR',
            'shipping_country' => 'ÜLKE',
            'shipping_postcode' => 'POSTA KODU',
        ]);


        // BURADA KULLANICI SORGUSU YAPMALISINIZ.
        $query = $db->from('kullanicilar')
            ->where('Id', $userID) // Sessiondan geliyor
            ->all();


        // EĞER KULLANICI VARSA İF'İN BLOGU ÇALIŞIR
        if(count($query) > 0){



            // SİPARİŞ VERİLMEDEN KULLANICI VERİ TABANINA KAYDEDİLİR.
            // SHOPİER DÖNÜŞÜNDE VERİ TABANINDAN KULLANICI BULUNUP İŞLEMLER YAPILACAK
            $insert = $db->insert('shopier2')
            ->set(array(
                "KullaniciId" => $userID, // KULLANICININ ID'Sİ
                "KullaniciAdi" => $query[0]['KullaniciAdi'], // KULLANICI ADI
                "email" => $query[0]['Email'], // EMAİL ADRESİ
                "OdemeTutari" => $tutar, // YÜKLENECEK MİKTAR
                "SiparisId" => "SİPARİŞ ID GELECEK",
                "Durum" => 'Beklemede'
            ));


            // ÖDEME BÖLÜMÜNE YÖNLENDİRME İŞLEMİ
            die($shopier->run(ORDER_ID, ORDER_AMOUNT, CALLBACK_URL));


        }else{
            echo '<script>swal("Bilgi", "Bakiye yükleme işlemi şuan yapılamıyor.", "info") </script>';
        }
    }
}

Yukarıda ki yönlendirme yaptığımız dosyayı doğru ayarlarsanız sipariş bölümü sorunsuz açılacaktır.
Şimdi dönüşü alarak kullanıcı üzerinde istediğimiz işlemi yapalım.


PHP:
$key='XXXXXXXXXXX'; //Shopier panelindeki bildirim şifresi
$username='XXXXXXXXXX'; //Shopier panelindeki bildirim kullanıcı adı
//Gelmesi gereken veriler kontrol edilir
if (!( (isset($_POST['res'])) && (isset($_POST['hash']))))
{
echo "missing parameter";
die();
}
//Ozet kontrolü yapılır
$hash=hash_hmac('sha256',$_POST['res'].$username,$key,false);
if (strcmp($hash,$_POST['hash'])!=0)
{
die();
}
//Veriler alınır
$json_result=base64_decode($_POST['res']);
$array_result=json_decode($json_result,true);
//Verilerle ilgili yapmanız gereken işlemleri yapınız. Bildirim çeşitli ağ sorunları nedeni
ile birden fazla kez gelebilir, bu nedenle ilk olarak orderid parametresi kullanılarak bu
siparisin daha once islenip islenmedigini kontrol ediniz.
$email=$array_result['email'];
$orderid=$array_result['orderid'];
$currency=$array_result['currency']; // 0..TL,1..USD, 2...EUR
$price=$array_result['price'];
$buyername=$array_result['buyername'];
$buyersurname=$array_result['buyersurname'];
$productcount=$array_result['productcount'];
$productid=$array_result['productid'];
$customernote=$array_result['customernote']; //müsterinizin size yazmıs oldugu not alanı
$istest=$array_result['istest']; //0..canlı, 1..test
//Islem basarili oldugunda success yazılarak, Shopier tarafında bildirimin basarili
geldigi dogrulanmıs olunur
echo "success";

Shopier’ın web sitesine giriş yaptığınızda Özelleştirme->Sipariş bildirim ayarı bölümüne geliniz.
Oradaki Bildirim kullanıcı adı ve şifresini geri dönüş bölümünde kullanmalısınız.
Biz siparişi verirken kullanıcı bilgilerini ve sipariş id’yi veri tabanına kaydetmiştik.
Shopier bize sipariş id’yi geri dönüyor. Sipariş id ve email adresi ile veri tabanından satırı bulup durumunun Beklemede olup olmadığını kontrol edin.
Eğer durum beklemede ise ödeme yapan kullanıcıya yaptığı miktarı yükleyin ve durumu Tamamlandı olarak değiştirin.
Durumunu değiştirmezseniz shopier tarafından yapılacak 2. bir post işleminde kullanıcıya tekrar bakiye yüklenecektir.
Bu işlemleri geri dönüşü aldığınız bölümde kontrol ettirmelisiniz. Anlamadığınız bölümleri yorum atarsanız cevaplamaya çalışacağım.
 

Bu çeriği görüntüleyen kullanıcılar (Kullanıcı: 0, Ziyaretçi: 3)

Hakkımızda

  • İçerik sağlayıcı paylaşım sitelerinden biri olan prej.net T.C.K 20.ci Madde ve 5651 Sayılı Kanun'un 4.cü maddesinin (2).ci fıkrasına göre ve kullanıcıların sisteme kayıt olurken kabul ettikleri kurallar çerçevesinde tüm kullanıcılar yaptıkları paylaşımlardan sorumludur. Prej.net karşılaştığınız yazılımsal sorunlar için yardım alabileceğiniz veya sorun yaşayan üyelere yardım edebileceğiniz bir platform. Yaptığınız yazılımlar hakkında üyeler ile beyin fırtınası yapabilir ve daha iyi seviyelere getirebilirsiniz.

Yararlı Bağlantılar

User Menu