mews / pos-bundle
Virtual POS bundle for Turkey banks.
Installs: 25
Dependents: 0
Suggesters: 0
Security: 0
Stars: 5
Watchers: 3
Forks: 1
Open Issues: 0
Type:symfony-bundle
Requires
- php: >=7.4
- mews/pos: ^1.3
- symfony/config: ^4.0 | ^5.0 | ^6.0 | ^7.0
- symfony/dependency-injection: ^4.0 | ^5.0 | ^6.0 | ^7.0
- symfony/event-dispatcher: ^4.0 | ^5.0 | ^6.0 | ^7.0
- symfony/http-kernel: ^4.0 | ^5.0 | ^6.0 | ^7.0
- symfony/options-resolver: ^4.0 | ^5.0 | ^6.0 | ^7.0
Requires (Dev)
- nyholm/psr7: ^1.8
- psr/http-client: ^1.0
- symfony/framework-bundle: ^6.4
- symfony/http-client: ^6.4
- symfony/phpunit-bridge: ^6.4
- symfony/yaml: ^6.4
This package is auto-updated.
Last update: 2024-10-26 16:16:37 UTC
README
Temel Paket
Ana başlıklar
- Minimum Gereksinimler
- Kurulum
- Ornek 3D Secure Odeme
- Konfigurasyon Yapısı ve Örnekler
- API ve 3D Form verisini degiştirme
Minimum Gereksinimler
- PHP >= 7.4
- mews/pos ^1.3
- Symfony 4|5|6|7
Kurulum
-
$ composer require mews/pos-bundle
config/packages/mews_pos.yaml
dosyası oluşturun- ve içine bu alttaki config örneği ekleyin:
mews_pos: banks: estpos: # herhangi unique bir isim gateway_class: Mews\Pos\Gateways\EstV3Pos lang: !php/const Mews\Pos\PosInterface::LANG_TR # optional test_mode: false #optional, default: false; credentials: payment_model: !php/const Mews\Pos\PosInterface::MODEL_3D_SECURE merchant_id: 700xxxxxx user_name: ISXXXXXX #EstPos: kullanici adi user_password: ISYYYYY #EstPos: kullanici sifresi enc_key: TRPXXXXX gateway_endpoints: # ilgili ortamin (test/prod) URL'leriyle degistiriniz: payment_api: 'https://entegrasyon.asseco-see.com.tr/fim/api' gateway_3d: 'https://entegrasyon.asseco-see.com.tr/fim/est3Dgate' gateway_3d_host: 'https://sanalpos.sanalakpos.com.tr/fim/est3Dgate' # optional, 3D Host ödemeler için zorunlu yapikredi: gateway_class: Mews\Pos\Gateways\PosNet credentials: payment_model: !php/const Mews\Pos\PosInterface::MODEL_3D_SECURE merchant_id: 670XXXXXXX # Üye İşyeri Numarası. terminal_id: 67XXXXXX # Üye İşyeri Terminal Numaras user_name: 27XXX # Üye İşyeri POSNET Numarası enc_key: 10,92,92,02,02,02,02,02,01 # Şifreleme anahtar gateway_endpoints: payment_api: 'https://setmpos.ykb.com/PosnetWebService/XML' gateway_3d: 'https://setmpos.ykb.com/3DSWebService/YKBPaymentService'
Ornek 3D Secure Odeme
<?php namespace App\Controller; use Mews\Pos\Entity\Card\CreditCardInterface; use Mews\Pos\Exceptions\CardTypeNotSupportedException; use Mews\Pos\Exceptions\CardTypeRequiredException; use Mews\Pos\Exceptions\HashMismatchException; use Mews\Pos\Factory\CreditCardFactory; use Mews\Pos\Gateways\PayFlexV4Pos; use Mews\Pos\PosInterface; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\DependencyInjection\Attribute\TaggedIterator; use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\Routing\Annotation\Route; use Symfony\Component\Routing\Generator\UrlGeneratorInterface; #[Route('/payment/3d')] class SingleBankThreeDSecurePaymentController extends AbstractController { private string $paymentModel = PosInterface::MODEL_3D_HOST; public function __construct( /** * mews_pos.yaml'da birden fazla banka configurasyonu varsa, ilki default olarak inject edilecek */ private PosInterface $pos, /** * spesifik bir bankayi inject etmek istiyorsak: */ private PosInterface $yapikrediTest, private UrlGeneratorInterface $urlGenerator, /** * birden fazla banka oldugunda bu sekilde hepsine erisebilirsiniz * @var PosInterface[] */ #[TaggedIterator('mews_pos.gateway')] private iterable $banks, ) { // foreach ($this->banks as $bank) { // if ('estpos' === $bank->getAccount()->getBank()) { // // todo // } // } } /** * Kullanicidan kredi kart bilgileri alip buraya POST ediyoruz */ #[Route('/form', name: 'single_bank_payment_3d_redirect_form', methods: ['POST'])] public function form(Request $request) { $session = $request->getSession(); $transaction = $request->get('tx', PosInterface::TX_TYPE_PAY_AUTH); $callbackUrl = $this->urlGenerator->generate('single_bank_payment_3d_response', [], UrlGeneratorInterface::ABSOLUTE_URL); $order = $this->createNewOrder( $this->paymentModel, $callbackUrl, $request->getClientIp(), $request->get('currency', PosInterface::CURRENCY_TRY), $request->get('installment'), $request->get('lang', PosInterface::LANG_TR) ); $session->set('order', $order); $card = $this->createCard($this->pos, $request->request->all()); /** * PayFlex'te provizyonu (odemeyi) tamamlamak icin tekrar kredi kart bilgileri isteniyor, * bu yuzden kart bilgileri kaydediyoruz */ if ($this->pos::class === PayFlexV4Pos::class) { $session->set('card', $request->request->all()); } $session->set('tx', $transaction); try { $formData = $this->pos->get3DFormData($order, $this->paymentModel, $transaction, $card); } catch (\Throwable $e) { dd($e); } return $this->render('redirect-form.html.twig', [ 'formData' => $formData, ]); } /** * kullanici bankadan geri buraya redirect edilir */ #[Route('/response', name: 'single_bank_payment_3d_response')] public function response(Request $request) { $session = $request->getSession(); $transaction = $session->get('tx', PosInterface::TX_TYPE_PAY_AUTH); // bankadan POST veya GET ile veri gelmesi gerekiyor if (($request->getMethod() !== 'POST') // PayFlex-CP GET request ile cevapliyor && ($request->getMethod() === 'GET' && ($this->pos::class !== \Mews\Pos\Gateways\PayFlexCPV4Pos::class || [] === $request->query->all())) ) { return new RedirectResponse($request->getBaseUrl()); } $card = null; if ($this->pos::class === \Mews\Pos\Gateways\PayFlexV4Pos::class) { // bu gateway için ödemeyi tamamlarken tekrar kart bilgisi lazım. $savedCard = $session->get('card'); $card = $this->createCard($this->pos, $savedCard); $session->remove('card'); } $order = $session->get('order'); if (!$order) { throw new \Exception('Sipariş bulunamadı, session sıfırlanmış olabilir.'); } try { $this->pos->payment($this->paymentModel, $order, $transaction, $card); } catch (HashMismatchException $e) { dd($e); } catch (\Exception|\Error $e) { dd($e); } if ($this->pos->isSuccess()) { echo 'success'; dd($this->pos->getResponse()); } else { dd($response); } } private function createNewOrder( string $paymentModel, string $callbackUrl, string $ip, string $currency, ?int $installment = 0, string $lang = PosInterface::LANG_TR ): array { $orderId = date('Ymd').strtoupper(substr(uniqid(sha1(time())), 0, 4)); $order = [ 'id' => $orderId, 'amount' => 10.01, 'currency' => $currency, 'installment' => $installment, 'ip' => \filter_var( $ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 ) ? $ip : '127.0.0.1', ]; if (\in_array($paymentModel, [ PosInterface::MODEL_3D_SECURE, PosInterface::MODEL_3D_PAY, PosInterface::MODEL_3D_HOST, PosInterface::MODEL_3D_PAY_HOSTING, ], true)) { $order['success_url'] = $callbackUrl; $order['fail_url'] = $callbackUrl; } if ($lang) { //lang degeri verilmezse account (EstPosAccount) dili kullanilacak $order['lang'] = $lang; } return $order; } private function createCard(PosInterface $pos, array $card): CreditCardInterface { try { return CreditCardFactory::createForGateway( $pos, $card['number'], $card['year'], $card['month'], $card['cvv'], $card['name'], $card['type'] ?? null ); } catch (CardTypeRequiredException|CardTypeNotSupportedException $e) { dd($e); } catch (\LogicException $e) { dd($e); } } }
redirect-form.html.twig
:
<form method="{{ formData.method }}" action="{{ formData.gateway }}" class="redirect-form" role="form"> {% for key, value in formData.inputs %} <input type="hidden" name="{{ key }}" value="{{ value }}"> {% endfor %} <div class="text-center">Redirecting...</div> <hr> <div class="form-group text-center"> <button type="submit" class="btn btn-lg btn-block btn-success">Submit</button> </div> </form>
PHP Sessioni kullanıyorsanız bu ayarları da yapmanız gerekiyor:
# /config/packages/framework.yaml framework: session: cookie_secure: true cookie_samesite: none
KuveytPos TDV2.0.0 için ekstra veri eklemek zorunludur. Bunun EventListener ile yapabilirsiniz:
<?php namespace App\EventListener; use Mews\Pos\Event\RequestDataPreparedEvent; use Symfony\Component\EventDispatcher\Attribute\AsEventListener; /** * KuveytPos TDV2.0.0 odemenin calismasi icin zorunlu eklenmesi gereken alan var. */ #[AsEventListener(event: RequestDataPreparedEvent::class)] final class KuveytPosV2RequestDataPreparedEventListener { public function __invoke(RequestDataPreparedEvent $event): void { if ($event->getGatewayClass() !== \Mews\Pos\Gateways\KuveytPos::class) { return; } /** * ekstra eklenmesi gereken verileri isteseniz $order icine ekleyip sonra o verilere * $event->getOrder() ile erisebilirsiniz. */ $additionalRequestDataForKuveyt = [ 'DeviceData' => [ /** * DeviceChannel : DeviceData alanı içerisinde gönderilmesi beklenen işlemin yapıldığı cihaz bilgisi. * 2 karakter olmalıdır. 01-Mobil, 02-Web Browser için kullanılmalıdır. */ 'DeviceChannel' => '02', ], 'CardHolderData' => [ /** * BillAddrCity: Kullanılan kart ile ilişkili kart hamilinin fatura adres şehri. * Maksimum 50 karakter uzunluğunda olmalıdır. */ 'BillAddrCity' => 'İstanbul', /** * BillAddrCountry Kullanılan kart ile ilişkili kart hamilinin fatura adresindeki ülke kodu. * Maksimum 3 karakter uzunluğunda olmalıdır. * ISO 3166-1 sayısal üç haneli ülke kodu standardı kullanılmalıdır. */ 'BillAddrCountry' => '792', /** * BillAddrLine1: Kullanılan kart ile ilişkili kart hamilinin teslimat adresinde yer alan sokak vb. bilgileri içeren açık adresi. * Maksimum 150 karakter uzunluğunda olmalıdır. */ 'BillAddrLine1' => 'XXX Mahallesi XXX Caddesi No 55 Daire 1', /** * BillAddrPostCode: Kullanılan kart ile ilişkili kart hamilinin fatura adresindeki posta kodu. */ 'BillAddrPostCode' => '34000', /** * BillAddrState: CardHolderData alanı içerisinde gönderilmesi beklenen ödemede kullanılan kart ile ilişkili kart hamilinin fatura adresindeki il veya eyalet bilgisi kodu. * ISO 3166-2'de tanımlı olan il/eyalet kodu olmalıdır. */ 'BillAddrState' => '40', /** * Email: Kullanılan kart ile ilişkili kart hamilinin iş yerinde oluşturduğu hesapta kullandığı email adresi. * Maksimum 254 karakter uzunluğunda olmalıdır. */ 'Email' => 'xxxxx@gmail.com', 'MobilePhone' => [ /** * Cc: Kullanılan kart ile ilişkili kart hamilinin cep telefonuna ait ülke kodu. 1-3 karakter uzunluğunda olmalıdır. */ 'Cc' => '90', /** * Subscriber: Kullanılan kart ile ilişkili kart hamilinin cep telefonuna ait abone numarası. * Maksimum 15 karakter uzunluğunda olmalıdır. */ 'Subscriber' => '1234567899', ], ], ]; $requestData = $event->getRequestData(); $requestData = \array_merge_recursive($requestData, $additionalRequestDataForKuveyt); $event->setRequestData($requestData); } }