|
7 | 7 |
|
8 | 8 | - [Minimum Gereksinimler](#minimum-gereksinimler) |
9 | 9 | - [Kurulum](#kurulum) |
10 | | -- [Ornek 3D Secure Odeme](#farkli-banka-sanal-poslarini-eklemek) |
| 10 | +- [Servis Kullanımı](#servis-kullanımı) |
| 11 | +- [Örnek 3D Secure Ödeme](./docs/EXAMPLE_3D_SECURE_ODEME.md) |
11 | 12 | - [Konfigurasyon Yapısı ve Örnekler](./docs/EXAMPLE_CONFIGURATIONS.md) |
12 | 13 | - [API ve 3D Form verisini degiştirme](./docs/EXAMPLE-API-ISTEK-VE-3D-FORM-VERSINI-DEGISTIRME.md) |
13 | 14 | - [PosQuery Servisleri (geçmiş, taksit, BIN sorguları)](./docs/POS-QUERY.md) |
|
39 | 40 | gateway_3d: 'https://entegrasyon.asseco-see.com.tr/fim/est3Dgate' |
40 | 41 | gateway_3d_host: 'https://sanalpos.sanalakpos.com.tr/fim/est3Dgate' # optional, 3D Host ödemeler için zorunlu |
41 | 42 | gateway_configs: |
42 | | - test_mode: false # optional, default: false |
43 | | - lang: tr # optional, default: tr |
| 43 | + lang: !php/const Mews\Pos\PosInterface::LANG_TR # optional, default: LANG_TR |
44 | 44 | yapikredi: |
45 | 45 | gateway_class: Mews\Pos\Gateway\PosNetPos |
46 | 46 | credentials: |
|
53 | 53 | gateway_3d: 'https://setmpos.ykb.com/3DSWebService/YKBPaymentService' |
54 | 54 | ``` |
55 | 55 |
|
56 | | -### Ornek 3D Secure Odeme |
| 56 | +Diğer banka konfigurasyon örnekleri için bkz. [Konfigurasyon Yapısı ve Örnekler](./docs/EXAMPLE_CONFIGURATIONS.md). |
| 57 | + |
| 58 | +## Servis Kullanımı |
| 59 | + |
| 60 | +### POS Gateway inject etme |
| 61 | + |
| 62 | +`mews_pos.yaml`'daki **ilk banka** `PosInterface` tipiyle doğrudan inject edilebilir: |
| 63 | +
|
57 | 64 | ```php |
58 | | -<?php |
| 65 | +use Mews\Pos\PosInterface; |
| 66 | +
|
| 67 | +class MyService |
| 68 | +{ |
| 69 | + public function __construct(private PosInterface $pos) {} |
| 70 | +} |
| 71 | +``` |
59 | 72 |
|
60 | | -namespace App\Controller; |
| 73 | +**Belirli bir bankayı** inject etmek için argüman adını `mews_pos.yaml`'daki banka anahtarıyla eşleştirin: |
61 | 74 |
|
62 | | -use Mews\Pos\Entity\Card\CreditCardInterface; |
63 | | -use Mews\Pos\Exceptions\CardTypeNotSupportedException; |
64 | | -use Mews\Pos\Exceptions\CardTypeRequiredException; |
65 | | -use Mews\Pos\Exceptions\HashMismatchException; |
66 | | -use Mews\Pos\Factory\CreditCardFactory; |
67 | | -use Mews\Pos\Gateway\PayFlexV4Pos; |
| 75 | +```php |
68 | 76 | use Mews\Pos\PosInterface; |
69 | | -use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; |
70 | | -use Symfony\Component\DependencyInjection\Attribute\TaggedIterator; |
71 | | -use Symfony\Component\HttpFoundation\RedirectResponse; |
72 | | -use Symfony\Component\HttpFoundation\Request; |
73 | | -use Symfony\Component\Routing\Annotation\Route; |
74 | | -use Symfony\Component\Routing\Generator\UrlGeneratorInterface; |
75 | 77 |
|
76 | | -#[Route('/payment/3d')] |
77 | | -class SingleBankThreeDSecurePaymentController extends AbstractController |
| 78 | +class MyService |
78 | 79 | { |
79 | | - private string $paymentModel = PosInterface::MODEL_3D_HOST; |
| 80 | + public function __construct( |
| 81 | + private PosInterface $asseco, // mews_pos.yaml'daki "asseco" bankası |
| 82 | + private PosInterface $yapikredi, // mews_pos.yaml'daki "yapikredi" bankası |
| 83 | + ) {} |
| 84 | +} |
| 85 | +``` |
| 86 | + |
| 87 | +**Tüm bankalara** erişmek için `TaggedIterator` kullanın: |
80 | 88 |
|
| 89 | +```php |
| 90 | +use Mews\Pos\PosInterface; |
| 91 | +use Symfony\Component\DependencyInjection\Attribute\TaggedIterator; |
| 92 | +
|
| 93 | +class MyService |
| 94 | +{ |
81 | 95 | public function __construct( |
82 | | - /** |
83 | | - * mews_pos.yaml'da birden fazla banka configurasyonu varsa, ilki default olarak inject edilecek |
84 | | - */ |
85 | | - private PosInterface $pos, |
86 | | - /** |
87 | | - * spesifik bir bankayi inject etmek istiyorsak: |
88 | | - */ |
89 | | - private PosInterface $yapikrediTest, |
90 | | - private UrlGeneratorInterface $urlGenerator, |
91 | | - /** |
92 | | - * birden fazla banka oldugunda bu sekilde hepsine erisebilirsiniz |
93 | | - * @var PosInterface[] |
94 | | - */ |
95 | 96 | #[TaggedIterator('mews_pos.gateway')] |
96 | 97 | private iterable $banks, |
97 | | - ) |
98 | | - { |
99 | | -// foreach ($this->banks as $bank) { |
100 | | -// if ('asseco' === $bank->getAccount()->getBankName()) { |
101 | | -// // todo |
102 | | -// } |
103 | | -// } |
104 | | - } |
105 | | -
|
106 | | - /** |
107 | | - * Kullanicidan kredi kart bilgileri alip buraya POST ediyoruz |
108 | | - */ |
109 | | - #[Route('/form', name: 'single_bank_payment_3d_redirect_form', methods: ['POST'])] |
110 | | - public function form(Request $request) |
111 | | - { |
112 | | - $session = $request->getSession(); |
113 | | -
|
114 | | - $transaction = $request->get('tx', PosInterface::TX_TYPE_PAY_AUTH); |
115 | | -
|
116 | | - $callbackUrl = $this->urlGenerator->generate('single_bank_payment_3d_response', [], UrlGeneratorInterface::ABSOLUTE_URL); |
117 | | - $order = $this->createNewOrder( |
118 | | - $this->paymentModel, |
119 | | - $callbackUrl, |
120 | | - $request->getClientIp(), |
121 | | - $request->get('currency', PosInterface::CURRENCY_TRY), |
122 | | - $request->get('installment'), |
123 | | - $request->get('lang', PosInterface::LANG_TR) |
124 | | - ); |
125 | | - $session->set('order', $order); |
126 | | -
|
127 | | - $card = $this->createCard($this->pos, $request->request->all()); |
128 | | -
|
129 | | - /** |
130 | | - * PayFlex'te provizyonu (odemeyi) tamamlamak icin tekrar kredi kart bilgileri isteniyor, |
131 | | - * bu yuzden kart bilgileri kaydediyoruz |
132 | | - */ |
133 | | - if ($this->pos::class === PayFlexV4Pos::class) { |
134 | | - $session->set('card', $request->request->all()); |
135 | | - } |
136 | | - $session->set('tx', $transaction); |
137 | | -
|
138 | | - try { |
139 | | - $formData = $this->pos->get3DFormData( |
140 | | - $order, |
141 | | - $this->paymentModel, |
142 | | - $transaction, |
143 | | - $card, |
144 | | - /** |
145 | | - * MODEL_3D_SECURE veya MODEL_3D_PAY ödemelerde kredi kart verileri olmadan |
146 | | - * form verisini oluşturmak için true yapabilirsiniz. |
147 | | - * Yine de bazı gatewaylerde kartsız form verisi oluşturulamıyor. |
148 | | - */ |
149 | | - false |
150 | | - ); |
151 | | - } catch (\Throwable $e) { |
152 | | - dd($e); |
153 | | - } |
154 | | -
|
155 | | - /** |
156 | | - * Bazı 3D Host gateway'leri (VakifKatilimPos, KuveytPos, vb.) doğrudan bir yönlendirme URL'i döner: |
157 | | - * method=GET ve inputs=[]. Bu durumda HTML form render etmek yerine doğrudan yönlendiriyoruz. |
158 | | - */ |
159 | | - if (!is_string($formData) && $formData['method'] === 'GET' && [] === $formData['inputs']) { |
160 | | - return new RedirectResponse($formData['gateway']); |
161 | | - } |
162 | | -
|
163 | | - return $this->render('redirect-form.html.twig', [ |
164 | | - 'formData' => $formData, |
165 | | - ]); |
166 | | - } |
167 | | -
|
168 | | -
|
169 | | - /** |
170 | | - * kullanici bankadan geri buraya redirect edilir |
171 | | - */ |
172 | | - #[Route('/response', name: 'single_bank_payment_3d_response')] |
173 | | - public function response(Request $request) |
174 | | - { |
175 | | - $session = $request->getSession(); |
176 | | -
|
177 | | - $transaction = $session->get('tx', PosInterface::TX_TYPE_PAY_AUTH); |
178 | | -
|
179 | | - // bankadan POST veya GET ile veri gelmesi gerekiyor |
180 | | - if (($request->getMethod() !== 'POST') |
181 | | - // PayFlex-CP GET request ile cevapliyor |
182 | | - && ($request->getMethod() === 'GET' && ($this->pos::class !== \Mews\Pos\Gateway\PayFlexCPV4Pos::class || [] === $request->query->all())) |
183 | | - ) { |
184 | | - return new RedirectResponse($request->getBaseUrl()); |
185 | | - } |
186 | | -
|
187 | | - $card = null; |
188 | | - if ($this->pos::class === \Mews\Pos\Gateway\PayFlexV4Pos::class) { |
189 | | - // bu gateway için ödemeyi tamamlarken tekrar kart bilgisi lazım. |
190 | | - $savedCard = $session->get('card'); |
191 | | - $card = $this->createCard($this->pos, $savedCard); |
192 | | - $session->remove('card'); |
193 | | - } |
194 | | -
|
195 | | - $order = $session->get('order'); |
196 | | - if (!$order) { |
197 | | - throw new \Exception('Sipariş bulunamadı, session sıfırlanmış olabilir.'); |
198 | | - } |
199 | | -
|
200 | | - // PayFlexCPV4 GET ile cevap veriyor, diğerleri POST |
201 | | - $gatewayResponseData = $this->pos::class === \Mews\Pos\Gateway\PayFlexCPV4Pos::class |
202 | | - ? $request->query->all() |
203 | | - : $request->request->all(); |
204 | | -
|
205 | | - try { |
206 | | - $response = $this->pos->payment($this->paymentModel, $order, $transaction, $card, $gatewayResponseData); |
207 | | - } catch (HashMismatchException $e) { |
208 | | - /** |
209 | | - * Bankadan gelen verilerin bankaya ait olmadığında bu exception oluşur. |
210 | | - * Veya Banka API bilgileriniz hatalı ise de oluşur. |
211 | | - * Eğer kütühaneden dolayı hash doğrulama hatası alıyorsanız, issue oluşturunuz. |
212 | | - * Issue çözülene kadar geçici olarak disable_3d_hash_check: true ayarla hash doğrulamasını devre dışı bırakabilirsiniz. |
213 | | - * Güvenlik açısından disable_3d_hash_check: false olarak kullanılması tavsiye edilmez. |
214 | | - */ |
215 | | - dd($e); |
216 | | - } catch (\Exception|\Error $e) { |
217 | | - dd($e); |
218 | | - } |
219 | | -
|
220 | | - if ($this->pos->isSuccess()) { |
221 | | - echo 'success'; |
222 | | - dd($response); |
223 | | - } else { |
224 | | - dd($response); |
225 | | - } |
226 | | - } |
227 | | -
|
228 | | - private function createNewOrder( |
229 | | - string $paymentModel, |
230 | | - string $callbackUrl, |
231 | | - string $ip, |
232 | | - string $currency, |
233 | | - ?int $installment = 0, |
234 | | - string $lang = PosInterface::LANG_TR |
235 | | - ): array |
236 | | - { |
237 | | - $orderId = date('Ymd').strtoupper(substr(uniqid(sha1(time())), 0, 4)); |
238 | | -
|
239 | | - $order = [ |
240 | | - 'id' => $orderId, |
241 | | - 'amount' => 10.01, |
242 | | - 'currency' => $currency, |
243 | | - 'installment' => $installment, |
244 | | - 'ip' => \filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) ? $ip : '127.0.0.1', |
245 | | - ]; |
246 | | -
|
247 | | - if (\in_array($paymentModel, [ |
248 | | - PosInterface::MODEL_3D_SECURE, |
249 | | - PosInterface::MODEL_3D_PAY, |
250 | | - PosInterface::MODEL_3D_HOST, |
251 | | - PosInterface::MODEL_3D_PAY_HOSTING, |
252 | | - ], true)) { |
253 | | - $order['success_url'] = $callbackUrl; |
254 | | - $order['fail_url'] = $callbackUrl; |
255 | | - } |
256 | | -
|
257 | | - if ($lang) { |
258 | | - $order['lang'] = $lang; |
259 | | - } |
260 | | -
|
261 | | - return $order; |
262 | | - } |
263 | | -
|
264 | | - private function createCard(PosInterface $pos, array $card): CreditCardInterface |
265 | | - { |
266 | | - try { |
267 | | - return CreditCardFactory::createForGateway( |
268 | | - $pos, |
269 | | - $card['number'], |
270 | | - $card['year'], |
271 | | - $card['month'], |
272 | | - $card['cvv'], |
273 | | - $card['name'], |
274 | | - $card['type'] ?? null |
275 | | - ); |
276 | | - } catch (CardTypeRequiredException|CardTypeNotSupportedException $e) { |
277 | | - dd($e); |
278 | | - } catch (\LogicException $e) { |
279 | | - dd($e); |
280 | | - } |
281 | | - } |
| 98 | + ) {} |
282 | 99 | } |
283 | 100 | ``` |
284 | 101 |
|
285 | | -`redirect-form.html.twig`: |
286 | | -```html |
287 | | -{% if formData is iterable %} |
288 | | - <form method="{{ formData.method }}" action="{{ formData.gateway }}" class="redirect-form" role="form"> |
289 | | - {% for key, value in formData.inputs %} |
290 | | - <input type="hidden" name="{{ key }}" value="{{ value }}"> |
291 | | - {% endfor %} |
292 | | - <div class="text-center">Redirecting...</div> |
293 | | - <hr> |
294 | | - <div class="form-group text-center"> |
295 | | - <button type="submit" class="btn btn-lg btn-block btn-success">Submit</button> |
296 | | - </div> |
297 | | - </form> |
298 | | -<script> |
299 | | - document.querySelector('form.redirect-form').submit(); |
300 | | -</script> |
301 | | -{% else %} |
302 | | - {{ formData | raw }} |
303 | | -{% endif %} |
| 102 | +Tam controller örneği için bkz. [Örnek 3D Secure Ödeme](./docs/EXAMPLE_3D_SECURE_ODEME.md). |
| 103 | + |
| 104 | +--- |
| 105 | + |
| 106 | +### PosQuery inject etme |
| 107 | + |
| 108 | +`PosQueryInterface`, ödeme işlemiyle ilişkili olmayan banka sorguları (işlem geçmişi, taksit oranları, BIN sorgusu vb.) için kullanılır. Her gateway PosQuery desteği sunmaz; bundle yalnızca `mews/pos` kütüphanesinin o gateway için bir PosQuery sınıfı tanımladığı durumlarda servisi oluşturur. |
| 109 | + |
| 110 | +`mews_pos.yaml`'daki **ilk banka** PosQuery destekliyorsa doğrudan inject edilebilir: |
| 111 | +
|
| 112 | +```php |
| 113 | +use Mews\Pos\PosQuery\PosQueryInterface; |
| 114 | +
|
| 115 | +class MyService |
| 116 | +{ |
| 117 | + public function __construct(private PosQueryInterface $posQuery) {} |
| 118 | +} |
| 119 | +``` |
| 120 | +
|
| 121 | +**Belirli bir bankayı** inject etmek için argüman adını banka anahtarıyla eşleştirin: |
| 122 | +
|
| 123 | +```php |
| 124 | +use Mews\Pos\PosQuery\PosQueryInterface; |
| 125 | +
|
| 126 | +class MyService |
| 127 | +{ |
| 128 | + public function __construct( |
| 129 | + private PosQueryInterface $asseco, |
| 130 | + private PosQueryInterface $yapikredi, |
| 131 | + ) {} |
| 132 | +} |
304 | 133 | ``` |
305 | 134 |
|
| 135 | +**Tüm PosQuery servislerine** erişmek için: |
| 136 | +
|
| 137 | +```php |
| 138 | +use Mews\Pos\PosQuery\PosQueryInterface; |
| 139 | +use Symfony\Component\DependencyInjection\Attribute\TaggedIterator; |
306 | 140 |
|
307 | | -PHP Sessioni kullanıyorsanız bu ayarları da yapmanız gerekiyor: |
308 | | -```yaml |
309 | | -# /config/packages/framework.yaml |
310 | | -framework: |
311 | | - session: |
312 | | - cookie_secure: true |
313 | | - cookie_samesite: none |
| 141 | +class MyService |
| 142 | +{ |
| 143 | + public function __construct( |
| 144 | + #[TaggedIterator('mews_pos.query')] |
| 145 | + private iterable $posQueries, |
| 146 | + ) {} |
| 147 | +} |
314 | 148 | ``` |
315 | 149 |
|
| 150 | +Tam örnek ve desteklenen sorgu tipleri için bkz. [PosQuery Servisleri](./docs/POS-QUERY.md). |
| 151 | +
|
| 152 | +--- |
| 153 | +
|
316 | 154 | License |
317 | 155 | ---- |
318 | 156 |
|
|
0 commit comments