payment finished
This commit is contained in:
@@ -50,6 +50,22 @@ app.get('/cart/:id', (req, res) => {
|
||||
});
|
||||
});
|
||||
|
||||
// delete cart with id
|
||||
app.delete('/cart/:id', (req, res) => {
|
||||
redisClient.del(req.params.id, (err, data) => {
|
||||
if(err) {
|
||||
console.log('ERROR', err);
|
||||
res.status(500).send(err);
|
||||
} else {
|
||||
if(data == 1) {
|
||||
res.send('OK');
|
||||
} else {
|
||||
res.status(404).send('cart not found');
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// update/create cart
|
||||
app.get('/add/:id/:sku/:qty', (req, res) => {
|
||||
// check quantity
|
||||
@@ -184,7 +200,20 @@ app.post('/shipping/:id', (req, res) => {
|
||||
price: shipping.cost,
|
||||
subtotal: shipping.cost
|
||||
};
|
||||
cart.items.push(item);
|
||||
// check shipping already in the cart
|
||||
var idx;
|
||||
var len = cart.items.length;
|
||||
for(idx = 0; idx < len; idx++) {
|
||||
if(cart.items[idx].sku == item.sku) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(idx == len) {
|
||||
// not already in cart
|
||||
cart.items.push(item);
|
||||
} else {
|
||||
cart.items[idx] = item;
|
||||
}
|
||||
cart.total = calcTotal(cart.items);
|
||||
// work out tax
|
||||
cart.tax = calcTax(cart.total);
|
||||
|
@@ -14,6 +14,12 @@ services:
|
||||
- "6379"
|
||||
networks:
|
||||
- robot-shop
|
||||
rabbitmq:
|
||||
image: rabbitmq:3.7-alpine
|
||||
ports:
|
||||
- "5672"
|
||||
networks:
|
||||
- robot-shop
|
||||
catalogue:
|
||||
build:
|
||||
context: catalogue
|
||||
@@ -67,6 +73,8 @@ services:
|
||||
build:
|
||||
context: payment
|
||||
image: steveww/rs-payment
|
||||
depends_on:
|
||||
- rabbitmq
|
||||
ports:
|
||||
- "8080"
|
||||
networks:
|
||||
|
@@ -8,6 +8,6 @@ COPY requirements.txt /app/
|
||||
|
||||
RUN pip install -r requirements.txt
|
||||
|
||||
COPY payment.py /app/
|
||||
COPY *.py /app/
|
||||
|
||||
CMD ["python", "payment.py"]
|
||||
|
14
payment/docker-compose.yaml
Normal file
14
payment/docker-compose.yaml
Normal file
@@ -0,0 +1,14 @@
|
||||
version: '3'
|
||||
services:
|
||||
rabbitmq:
|
||||
image: rabbitmq:3.7-alpine
|
||||
ports:
|
||||
- "5672"
|
||||
payment:
|
||||
build:
|
||||
context: .
|
||||
image: steveww/rs-payment
|
||||
depends_on:
|
||||
- rabbitmq
|
||||
ports:
|
||||
- "8080:8080"
|
@@ -1,9 +1,13 @@
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
import logging
|
||||
import uuid
|
||||
import requests
|
||||
from flask import Flask
|
||||
from flask import request
|
||||
from flask import jsonify
|
||||
from rabbitmq import Publisher
|
||||
|
||||
app = Flask(__name__)
|
||||
|
||||
@@ -21,9 +25,21 @@ def pay(id):
|
||||
req = requests.get('https://paypal.com/')
|
||||
app.logger.info('paypal returned {}'.format(req.status_code))
|
||||
|
||||
# Generate order id
|
||||
orderid = str(uuid.uuid4())
|
||||
queueOrder({ 'order': orderid, 'cart': cart })
|
||||
|
||||
# TDOD - order history
|
||||
|
||||
return 'OK'
|
||||
return jsonify({ 'order': orderid })
|
||||
|
||||
|
||||
def queueOrder(order):
|
||||
app.logger.info('queue order')
|
||||
publisher.publish(order)
|
||||
|
||||
# RabbitMQ
|
||||
publisher = Publisher(app.logger)
|
||||
|
||||
if __name__ == "__main__":
|
||||
sh = logging.StreamHandler(sys.stdout)
|
||||
|
48
payment/rabbitmq.py
Normal file
48
payment/rabbitmq.py
Normal file
@@ -0,0 +1,48 @@
|
||||
import json
|
||||
import pika
|
||||
|
||||
class Publisher:
|
||||
HOST = 'rabbitmq'
|
||||
VIRTUAL_HOST = '/'
|
||||
EXCHANGE='robot-shop'
|
||||
TYPE='direct'
|
||||
ROUTING_KEY = 'orders'
|
||||
|
||||
def __init__(self, logger):
|
||||
self._logger = logger
|
||||
self._params = pika.connection.ConnectionParameters(
|
||||
host=self.HOST,
|
||||
virtual_host=self.VIRTUAL_HOST,
|
||||
credentials=pika.credentials.PlainCredentials('guest', 'guest'))
|
||||
self._conn = None
|
||||
self._channel = None
|
||||
|
||||
def _connect(self):
|
||||
if not self._conn or self._conn.is_closed:
|
||||
self._conn = pika.BlockingConnection(self._params)
|
||||
self._channel = self._conn.channel()
|
||||
self._channel.exchange_declare(exchange=self.EXCHANGE, exchange_type=self.TYPE)
|
||||
self._logger.info('connected to broker')
|
||||
|
||||
def _publish(self, msg):
|
||||
self._channel.basic_publish(exchange=self.EXCHANGE,
|
||||
routing_key=self.ROUTING_KEY,
|
||||
body=json.dumps(msg).encode())
|
||||
self._logger.info('message sent')
|
||||
|
||||
#Publish msg, reconnecting if necessary.
|
||||
def publish(self, msg):
|
||||
if self._channel is None:
|
||||
self._connect()
|
||||
try:
|
||||
self._publish(msg)
|
||||
except pika.exceptions.ConnectionClosed:
|
||||
self._logger.info('reconnecting to queue')
|
||||
self._connect()
|
||||
self._publish(msg)
|
||||
|
||||
def close(self):
|
||||
if self._conn and self._conn.is_open:
|
||||
self._logger.info('closing queue connection')
|
||||
self._conn.close()
|
||||
|
@@ -1,3 +1,4 @@
|
||||
Flask
|
||||
requests
|
||||
pika
|
||||
instana
|
||||
|
@@ -154,3 +154,22 @@ table.credentials {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
/* payment */
|
||||
a.cont:visited {
|
||||
color: cyan;
|
||||
text-decoration: none;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
a.cont:link {
|
||||
color: cyan;
|
||||
text-decoration: none;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
a.cont:hover {
|
||||
color: white;
|
||||
text-decoration: none;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
|
@@ -316,18 +316,40 @@
|
||||
|
||||
robotshop.controller('paymentform', function($scope, $http, currentUser) {
|
||||
$scope.data = {};
|
||||
$scope.data.message = ' ';
|
||||
$scope.data.buttonDisabled = false;
|
||||
$scope.data.cont = false;
|
||||
$scope.data.uniqueid = currentUser.uniqueid;
|
||||
$scope.data.cart = currentUser.cart;
|
||||
|
||||
$scope.pay = function() {
|
||||
$scope.data.buttonDisabled = true;
|
||||
$http({
|
||||
url: '/api/payment/pay/' + $scope.data.uniqueid,
|
||||
method: 'POST',
|
||||
data: $scope.data.cart
|
||||
}).then((res) => {
|
||||
console.log('payment ok');
|
||||
console.log('order', res.data);
|
||||
$scope.data.message = 'Order placed ' + res.data.orderid;
|
||||
// clear down cart
|
||||
$scope.data.cart = {
|
||||
total: 0,
|
||||
items: []
|
||||
};
|
||||
currentUser.cart = $scope.data.cart;
|
||||
$scope.data.cont = true;
|
||||
$http({
|
||||
url: '/api/cart/cart/' + $scope.data.uniqueid,
|
||||
method: 'DELETE'
|
||||
}).then((res) => {
|
||||
console.log('cart deleted ok');
|
||||
}).catch((e) => {
|
||||
console.log('ERROR cart delete', e);
|
||||
});
|
||||
}).catch((e) => {
|
||||
console.log('ERROR', e);
|
||||
$scope.data.message = 'ERROR placing order';
|
||||
$scope.data.buttonDisabled = false;
|
||||
});
|
||||
};
|
||||
|
||||
|
@@ -1,9 +1,6 @@
|
||||
<!-- payment template -->
|
||||
<div>
|
||||
<h3>Review your order</h3>
|
||||
<div ng-if="data.cart.total == 0">
|
||||
Your cart is empty, get shopping
|
||||
</div>
|
||||
<div ng-if="data.cart.total != 0">
|
||||
<table>
|
||||
<tr>
|
||||
@@ -31,9 +28,16 @@
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="3">
|
||||
<button ng-click="pay();">Pay with Paypal</button>
|
||||
<button ng-disabled="data.buttonDisabled" ng-click="pay();">Pay with Paypal</button>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<div class="message">
|
||||
{{ data.message }}
|
||||
</div>
|
||||
<div ng-if="data.cont">
|
||||
Thankyou for your order
|
||||
<a class="cont" href="/">Continue shopping</a>
|
||||
</div>
|
||||
</div>
|
||||
|
Reference in New Issue
Block a user