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
|
// update/create cart
|
||||||
app.get('/add/:id/:sku/:qty', (req, res) => {
|
app.get('/add/:id/:sku/:qty', (req, res) => {
|
||||||
// check quantity
|
// check quantity
|
||||||
@@ -184,7 +200,20 @@ app.post('/shipping/:id', (req, res) => {
|
|||||||
price: shipping.cost,
|
price: shipping.cost,
|
||||||
subtotal: 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);
|
cart.total = calcTotal(cart.items);
|
||||||
// work out tax
|
// work out tax
|
||||||
cart.tax = calcTax(cart.total);
|
cart.tax = calcTax(cart.total);
|
||||||
|
@@ -14,6 +14,12 @@ services:
|
|||||||
- "6379"
|
- "6379"
|
||||||
networks:
|
networks:
|
||||||
- robot-shop
|
- robot-shop
|
||||||
|
rabbitmq:
|
||||||
|
image: rabbitmq:3.7-alpine
|
||||||
|
ports:
|
||||||
|
- "5672"
|
||||||
|
networks:
|
||||||
|
- robot-shop
|
||||||
catalogue:
|
catalogue:
|
||||||
build:
|
build:
|
||||||
context: catalogue
|
context: catalogue
|
||||||
@@ -67,6 +73,8 @@ services:
|
|||||||
build:
|
build:
|
||||||
context: payment
|
context: payment
|
||||||
image: steveww/rs-payment
|
image: steveww/rs-payment
|
||||||
|
depends_on:
|
||||||
|
- rabbitmq
|
||||||
ports:
|
ports:
|
||||||
- "8080"
|
- "8080"
|
||||||
networks:
|
networks:
|
||||||
|
@@ -8,6 +8,6 @@ COPY requirements.txt /app/
|
|||||||
|
|
||||||
RUN pip install -r requirements.txt
|
RUN pip install -r requirements.txt
|
||||||
|
|
||||||
COPY payment.py /app/
|
COPY *.py /app/
|
||||||
|
|
||||||
CMD ["python", "payment.py"]
|
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 os
|
||||||
import sys
|
import sys
|
||||||
|
import time
|
||||||
import logging
|
import logging
|
||||||
|
import uuid
|
||||||
import requests
|
import requests
|
||||||
from flask import Flask
|
from flask import Flask
|
||||||
from flask import request
|
from flask import request
|
||||||
|
from flask import jsonify
|
||||||
|
from rabbitmq import Publisher
|
||||||
|
|
||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
|
|
||||||
@@ -21,9 +25,21 @@ def pay(id):
|
|||||||
req = requests.get('https://paypal.com/')
|
req = requests.get('https://paypal.com/')
|
||||||
app.logger.info('paypal returned {}'.format(req.status_code))
|
app.logger.info('paypal returned {}'.format(req.status_code))
|
||||||
|
|
||||||
|
# Generate order id
|
||||||
|
orderid = str(uuid.uuid4())
|
||||||
|
queueOrder({ 'order': orderid, 'cart': cart })
|
||||||
|
|
||||||
# TDOD - order history
|
# 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__":
|
if __name__ == "__main__":
|
||||||
sh = logging.StreamHandler(sys.stdout)
|
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
|
Flask
|
||||||
requests
|
requests
|
||||||
|
pika
|
||||||
instana
|
instana
|
||||||
|
@@ -154,3 +154,22 @@ table.credentials {
|
|||||||
text-align: right;
|
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) {
|
robotshop.controller('paymentform', function($scope, $http, currentUser) {
|
||||||
$scope.data = {};
|
$scope.data = {};
|
||||||
|
$scope.data.message = ' ';
|
||||||
|
$scope.data.buttonDisabled = false;
|
||||||
|
$scope.data.cont = false;
|
||||||
$scope.data.uniqueid = currentUser.uniqueid;
|
$scope.data.uniqueid = currentUser.uniqueid;
|
||||||
$scope.data.cart = currentUser.cart;
|
$scope.data.cart = currentUser.cart;
|
||||||
|
|
||||||
$scope.pay = function() {
|
$scope.pay = function() {
|
||||||
|
$scope.data.buttonDisabled = true;
|
||||||
$http({
|
$http({
|
||||||
url: '/api/payment/pay/' + $scope.data.uniqueid,
|
url: '/api/payment/pay/' + $scope.data.uniqueid,
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
data: $scope.data.cart
|
data: $scope.data.cart
|
||||||
}).then((res) => {
|
}).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) => {
|
}).catch((e) => {
|
||||||
console.log('ERROR', e);
|
console.log('ERROR', e);
|
||||||
|
$scope.data.message = 'ERROR placing order';
|
||||||
|
$scope.data.buttonDisabled = false;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -1,9 +1,6 @@
|
|||||||
<!-- payment template -->
|
<!-- payment template -->
|
||||||
<div>
|
<div>
|
||||||
<h3>Review your order</h3>
|
<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">
|
<div ng-if="data.cart.total != 0">
|
||||||
<table>
|
<table>
|
||||||
<tr>
|
<tr>
|
||||||
@@ -31,9 +28,16 @@
|
|||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td colspan="3">
|
<td colspan="3">
|
||||||
<button ng-click="pay();">Pay with Paypal</button>
|
<button ng-disabled="data.buttonDisabled" ng-click="pay();">Pay with Paypal</button>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</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>
|
</div>
|
||||||
|
Reference in New Issue
Block a user