Create an account


Welcome, Guest
You have to register before you can post on our site.

Username
  

Password
  





Search Forums

(Advanced Search)

Forum Statistics
» Members: 20,161
» Latest member: hotswagonme
» Forum threads: 21,831
» Forum posts: 22,710

Full Statistics

Online Users
There are currently 768 online users.
» 0 Member(s) | 762 Guest(s)
Applebot, Baidu, Bing, DuckDuckGo, Google, Yandex

 
  (Indie Deal) FREE Last Dream, 2K Sale, Core Keeper & Quantum Break
Posted by: xSicKxBot - 03-23-2022, 11:50 AM - Forum: Deals or Specials - No Replies

FREE Last Dream, 2K Sale, Core Keeper & Quantum Break

Last Dream FREEbie
[freebies.indiegala.com]
NEW FREEbie: Last Dream incorporates the best features of classic RPGs: replayability & complete immersion into a vast world, rich with detail
https://www.youtube.com/watch?v=-bsTaudFzNc
2K Sale, up to 95% OFF
[www.indiegala.com]
(Final weekend) Any purchase made on IndieGala (be it store deals or bundles) will be rewarding you instantly and handsomely, directly into your IndieGala account, with 5% of your final purchase (in the form of GalaCredit).
https://www.youtube.com/watch?v=r36nBuRGzVk
Stay Inside, Stay Safe and Enjoy Good Games.
Check out IndieGala on Twitter, YouTube & Facebook[www.facebook.com]


https://steamcommunity.com/groups/indieg...3537199178

Print this item

  (Free Game Key) Brothers - A Tale of Two Sons - Free Epic Game
Posted by: xSicKxBot - 03-23-2022, 11:50 AM - Forum: Deals or Specials - No Replies

Brothers - A Tale of Two Sons - Free Epic Game

Visit the store page and add the game to your account:

Brothers - A Tale of Two Sons[store.epicgames.com]

The game is free to keep until Feb 24th 2022 - 16:00 UTC.

Next week's freebie:
Cris Tales

We are welcoming everyone to join our discord[discord.gg]. We are more active there on finding giveaways, small or large, and there are daily raffles you can participate.

?GrabFreeGames.com ?Twitter ?Steam Curator ?Facebook[fb.me]?Discord[discord.gg]
❤️Support us: ✔️HumbleBundle Partner[www.humblebundle.com] Epic Tag: GrabFreeGames


https://steamcommunity.com/groups/GrabFr...1588580559

Print this item

  PC - Guild Wars 2: End of Dragons
Posted by: xSicKxBot - 03-23-2022, 11:50 AM - Forum: New Game Releases - No Replies

Guild Wars 2: End of Dragons



Guild Wars 2: End of Dragons is the third expansion for the award-winning and critically acclaimed MMORPG Guild Wars 2. The dragon cycle that has sustained and blighted Tyria for ages is collapsing. Mortal hearts and choices will define this moment in history—and echo in the future forever.

Publisher: NCSOFT

Release Date: Feb 28, 2022




https://www.metacritic.com/game/pc/guild...of-dragons

Print this item

  Quarkus: Modernize “helloworld” JBoss EAP quickstart, Part 1
Posted by: xSicKxBot - 03-22-2022, 05:39 PM - Forum: Java Language, JVM, and the JRE - No Replies

Quarkus: Modernize “helloworld” JBoss EAP quickstart, Part 1

Quarkus is, in its own words, “Supersonic subatomic Java” and a “Kubernetes native Java stack tailored for GraalVM & OpenJDK HotSpot, crafted from the best of breed Java libraries and standards.” For the purpose of illustrating how to modernize an existing Java application to Quarkus, I will use the Red Hat JBoss Enterprise Application Platform (JBoss EAP) quickstarts helloworld quickstart as sample of a Java application builds using technologies (CDI and Servlet 3) supported in Quarkus.

It’s important to note that both Quarkus and JBoss EAP rely on providing developers with tools based—as much as possible—on standards. If your application is not already running on JBoss EAP, there’s no problem. You can migrate it from your current application server to JBoss EAP using the Red Hat Application Migration Toolkit. After that, the final and working modernized version of the code is available in the https://github.com/mrizzi/jboss-eap-quickstarts/tree/quarkus repository inside the helloworld module.

This article is based on the guides Quarkus provides, mainly Creating Your First Application and Building a Native Executable.

Get the code


To start, clone the JBoss EAP quickstarts repository locally, running:

$ git clone https://github.com/jboss-developer/jboss...starts.git Cloning into 'jboss-eap-quickstarts'... remote: Enumerating objects: 148133, done. remote: Total 148133 (delta 0), reused 0 (delta 0), pack-reused 148133 Receiving objects: 100% (148133/148133), 59.90 MiB | 7.62 MiB/s, done. Resolving deltas: 100% (66476/66476), done. $ cd jboss-eap-quickstarts/helloworld/

Try plain, vanilla helloworld


The name of the quickstart is a strong clue about what this application does, but let’s follow a scientific approach in modernizing this code, so first things first: Try the application as it is.

Deploy helloworld


  1. Open a terminal and navigate to the root of the JBoss EAP directory EAP_HOME (which you can download).
  2. Start the JBoss EAP server with the default profile by typing the following command:
$ EAP_HOME/bin/standalone.sh 

Note: For Windows, use the EAP_HOME\bin\standalone.bat script.

After a few seconds, the log should look like:

[org.jboss.as] (Controller Boot Thread) WFLYSRV0025: JBoss EAP 7.2.0.GA (WildFly Core 6.0.11.Final-redhat-00001) started in 3315ms - Started 306 of 527 services (321 services are lazy, passive or on-demand)
  1. Open http://127.0.0.1:8080 in a browser, and a page like Figure 1 should appear:
The JBoss EAP home page.

Figure 1: The JBoss EAP home page.

  1. Following instructions from Build and Deploy the Quickstart, deploy the helloworld quickstart and execute (from the project root directory) the command:
$ mvn clean install wildfly:deploy 

This command should end successfully with a log like this:

[INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 8.224 s 

The helloworld application has now been deployed for the first time in JBoss EAP in about eight seconds.

Test helloworld


Following the Access the Application guide, open http://127.0.0.1:8080/helloworld in the browser and see the application page, as shown in Figure 2:

JBoss EAP's Hello World.

Figure 2: JBoss EAP’s Hello World.

Make changes


Change the createHelloMessage(String name) input parameter from World to Marco (my ego is cheap):

writer.println("<h1>" + helloService.createHelloMessage("Marco") + "</h1>");

Execute again the command:

$ mvn clean install wildfly:deploy 

and then refresh the web page in the browser to check the message displayed changes, as shown in Figure 3:

JBoss EAP's Hello Marco.

Figure 3: JBoss EAP’s Hello Marco.

Undeploy helloworld and shut down


If you want to undeploy (optional) the application before shutting down JBoss EAP, run the following command:

$ mvn clean install wildfly:undeploy 

To shut down the JBoss EAP instance, enter Ctrl+C in the terminal where it’s running.

Let’s modernize helloworld


Now we can leave the original helloworld behind and update it.

Create a new branch


Create a new working branch once the quickstart project finishes executing:

$ git checkout -b quarkus 7.2.0.GA 

Change the pom.xml file


The time has come to start changing the application. starting from the pom.xml file. From the helloworld folder, run the following command to let Quarkus add XML blocks:

$ mvn io.quarkus:quarkus-maven-plugin:0.23.2:create 

This article uses the 0.23.2 version. To know which is the latest version is, please refer to https://github.com/quarkusio/quarkus/releases/latest/, since the Quarkus release cycles are short.

This command changed the pom.xml, file adding:

  • The property <quarkus.version> to define the Quarkus version to be used.
  • The <dependencyManagement> block to import the Quarkus bill of materials (BOM). In this way, there’s no need to add the version to each Quarkus dependency.
  • The quarkus-maven-plugin plugin responsible for packaging the application, and also providing the development mode.
  • The native profile to create application native executables.

Further changes required to pom.xml, to be done manually:

  1. Move the <groupId> tag outside of the <parent> block, and above the <artifactId> tag. Because we remove the <parent> block in the next step, the <groupId> must be preserved.
  2. Remove the <parent> block: The application doesn’t need the JBoss parent pom anymore to run with Quarkus.
  3. Add the <version> tag (below the <artifactId> tag) with the value you prefer.
  4. Remove the <packaging> tag: The application won’t be a WAR anymore, but a plain JAR.
  5. Change the following dependencies:
    1. Replace the javax.enterprise:cdi-api dependency with io.quarkus:quarkus-arc, removing <scope>provided</scope> because—as stated in the documentation—this Quarkus extension provides the CDI dependency injection.
    2. Replace the org.jboss.spec.javax.servlet:jboss-servlet-api_4.0_spec dependency with io.quarkus:quarkus-undertow, removing the <scope>provided</scope>, because—again as stated in the documentation—this is the Quarkus extension that provides support for servlets.
    3. Remove the org.jboss.spec.javax.annotation:jboss-annotations-api_1.3_spec dependency because it’s coming with the previously changed dependencies.

The pom.xml file’s fully changed version is available at https://github.com/mrizzi/jboss-eap-quickstarts/blob/quarkus/helloworld/pom.xml.

Note that the above mvn io.quarkus:quarkus-maven-plugin:0.23.2:create command, besides the changes to the pom.xml file, added components to the project. The added file and folders are:

  • The files mvnw and mvnw.cmd, and .mvn folder: The Maven Wrapper allows you to run Maven projects with a specific version of Maven without requiring that you install that specific Maven version.
  • The docker folder (in src/main/): This folder contains example Dockerfile files for both native and jvm modes (together with a .dockerignore file).
  • The resources folder (in src/main/): This folder contains an empty application.properties file and the sample Quarkus landing page index.html (more in the section “Run the modernized helloworld“).

Run helloworld


To test the application, use quarkus:dev, which runs Quarkus in development mode (more details on Development Mode here).

Note: We expect this step to fail as changes are still required to the application, as detailed in this section.

Now run the command to check if and how it works:

$ ./mvnw compile quarkus:dev [INFO] Scanning for projects... [INFO] [INFO] ----------------< org.jboss.eap.quickstarts:helloworld >---------------- [INFO] Building Quickstart: helloworld quarkus [INFO] --------------------------------[ war ]--------------------------------- [INFO] [INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ helloworld --- [INFO] Using 'UTF-8' encoding to copy filtered resources. [INFO] Copying 2 resources [INFO] [INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ helloworld --- [INFO] Nothing to compile - all classes are up to date [INFO] [INFO] --- quarkus-maven-plugin:0.23.2:dev (default-cli) @ helloworld --- Listening for transport dt_socket at address: 5005 INFO [io.qua.dep.QuarkusAugmentor] Beginning quarkus augmentation INFO [org.jbo.threads] JBoss Threads version 3.0.0.Final ERROR [io.qua.dev.DevModeMain] Failed to start quarkus: java.lang.RuntimeException: io.quarkus.builder.BuildException: Build failure: Build failed due to errors [error]: Build step io.quarkus.arc.deployment.ArcProcessor#validate threw an exception: javax.enterprise.inject.spi.DeploymentException: javax.enterprise.inject.UnsatisfiedResolutionException: Unsatisfied dependency for type org.jboss.as.quickstarts.helloworld.HelloService and qualifiers [@Default] - java member: org.jboss.as.quickstarts.helloworld.HelloWorldServlet#helloService - declared on CLASS bean [types=[javax.servlet.ServletConfig, java.io.Serializable, org.jboss.as.quickstarts.helloworld.HelloWorldServlet, javax.servlet.GenericServlet, javax.servlet.Servlet, java.lang.Object, javax.servlet.http.HttpServlet], qualifiers=[@Default, @Any], target=org.jboss.as.quickstarts.helloworld.HelloWorldServlet] at io.quarkus.arc.processor.BeanDeployment.processErrors(BeanDeployment.java:841) at io.quarkus.arc.processor.BeanDeployment.init(BeanDeployment.java:214) at io.quarkus.arc.processor.BeanProcessor.initialize(BeanProcessor.java:106) at io.quarkus.arc.deployment.ArcProcessor.validate(ArcProcessor.java:249) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at io.quarkus.deployment.ExtensionLoader$1.execute(ExtensionLoader.java:780) at io.quarkus.builder.BuildContext.run(BuildContext.java:415) at org.jboss.threads.ContextClassLoaderSavingRunnable.run(ContextClassLoaderSavingRunnable.java:35) at org.jboss.threads.EnhancedQueueExecutor.safeRun(EnhancedQueueExecutor.java:2011) at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.doRunTask(EnhancedQueueExecutor.java:1535) at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1426) at java.lang.Thread.run(Thread.java:748) at org.jboss.threads.JBossThread.run(JBossThread.java:479) Caused by: javax.enterprise.inject.UnsatisfiedResolutionException: Unsatisfied dependency for type org.jboss.as.quickstarts.helloworld.HelloService and qualifiers [@Default] - java member: org.jboss.as.quickstarts.helloworld.HelloWorldServlet#helloService - declared on CLASS bean [types=[javax.servlet.ServletConfig, java.io.Serializable, org.jboss.as.quickstarts.helloworld.HelloWorldServlet, javax.servlet.GenericServlet, javax.servlet.Servlet, java.lang.Object, javax.servlet.http.HttpServlet], qualifiers=[@Default, @Any], target=org.jboss.as.quickstarts.helloworld.HelloWorldServlet] at io.quarkus.arc.processor.Beans.resolveInjectionPoint(Beans.java:428) at io.quarkus.arc.processor.BeanInfo.init(BeanInfo.java:371) at io.quarkus.arc.processor.BeanDeployment.init(BeanDeployment.java:206) ... 14 more 

It failed. Why? What happened?

The UnsatisfiedResolutionException exception refers to the HelloService class, which is a member of the HelloWorldServlet class (java member: org.jboss.as.quickstarts.helloworld.HelloWorldServlet#helloService). The problem is that HelloWorldServlet needs an injected instance of HelloService, but it can not be found (even if the two classes are in the very same package).

It’s time to return to Quarkus guides to leverage the documentation and understand how @Inject—and hence Contexts and Dependency Injection (CDI)—works in Quarkus, thanks to the Contexts and Dependency Injection guide. In the Bean Discovery paragraph, it says, “Bean classes that don’t have a bean defining annotation are not discovered.”

Looking at the HelloService class, it’s clear there’s no bean defining annotation, and one has to be added to have Quarkus to discover the bean. So, because it’s a stateless object, it’s safe to add the @ApplicationScoped annotation:

@ApplicationScoped public class HelloService { 

Note: The IDE should prompt you to add the required package shown here (add it manually if need be):

import javax.enterprise.context.ApplicationScoped; 

If you’re in doubt about which scope to apply when the original bean has no scope defined, please refer to the JSR 365: Contexts and Dependency Injection for Java 2.0—Default scope documentation.

Now, try again to run the application, executing again the ./mvnw compile quarkus:dev command:

$ ./mvnw compile quarkus:dev [INFO] Scanning for projects... [INFO] [INFO] ----------------< org.jboss.eap.quickstarts:helloworld >---------------- [INFO] Building Quickstart: helloworld quarkus [INFO] --------------------------------[ war ]--------------------------------- [INFO] [INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ helloworld --- [INFO] Using 'UTF-8' encoding to copy filtered resources. [INFO] Copying 2 resources [INFO] [INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ helloworld --- [INFO] Changes detected - recompiling the module! [INFO] Compiling 2 source files to /home/mrizzi/git/forked/jboss-eap-quickstarts/helloworld/target/classes [INFO] [INFO] --- quarkus-maven-plugin:0.23.2:dev (default-cli) @ helloworld --- Listening for transport dt_socket at address: 5005 INFO [io.qua.dep.QuarkusAugmentor] (main) Beginning quarkus augmentation INFO [io.qua.dep.QuarkusAugmentor] (main) Quarkus augmentation completed in 576ms INFO [io.quarkus] (main) Quarkus 0.23.2 started in 1.083s. Listening on: http://0.0.0.0:8080 INFO [io.quarkus] (main) Profile dev activated. Live Coding activated. INFO [io.quarkus] (main) Installed features: [cdi] 

This time the application runs successfully.

Run the modernized helloworld


As the terminal log suggests, open a browser to http://0.0.0.0:8080(the default Quarkus landing page), and the page shown in Figure 4 appears:

The Quarkus dev landing page.

Figure 4: The Quarkus dev landing page.

This application has the following context’s definition in the WebServlet annotation:

@WebServlet("/HelloWorld") public class HelloWorldServlet extends HttpServlet { 

Hence, you can browse to http://0.0.0.0:8080/HelloWorldto reach the page shown in Figure 5:

The Quarkus dev Hello World page.

Figure 5: The Quarkus dev Hello World page.

It works!

Make changes


Please, pay attention to the fact that the ./mvnw compile quarkus:dev command is still running, and we’re not going to stop it. Now, try to apply the same—very trivial—change to the code and see how Quarkus improves the developer experience:

writer.println("<h1>" + helloService.createHelloMessage("Marco") + "</h1>");

Save the file, and then refresh the web page to check that Hello Marco appears, as shown in Figure 6:

The Quarkus dev Hello Marco page.

Figure 6: The Quarkus dev Hello Marco page.

Take time to check the terminal output:

INFO [io.qua.dev] (vert.x-worker-thread-3) Changed source files detected, recompiling [/home/mrizzi/git/forked/jboss-eap-quickstarts/helloworld/src/main/java/org/jboss/as/quickstarts/helloworld/HelloWorldServlet.java] INFO [io.quarkus] (vert.x-worker-thread-3) Quarkus stopped in 0.003s INFO [io.qua.dep.QuarkusAugmentor] (vert.x-worker-thread-3) Beginning quarkus augmentation INFO [io.qua.dep.QuarkusAugmentor] (vert.x-worker-thread-3) Quarkus augmentation completed in 232ms INFO [io.quarkus] (vert.x-worker-thread-3) Quarkus 0.23.2 started in 0.257s. Listening on: http://0.0.0.0:8080 INFO [io.quarkus] (vert.x-worker-thread-3) Profile dev activated. Live Coding activated. INFO [io.quarkus] (vert.x-worker-thread-3) Installed features: [cdi] INFO [io.qua.dev] (vert.x-worker-thread-3) Hot replace total time: 0.371s 

Refreshing the page triggered the source code change detection and the Quarkus automagic “stop-and-start.” All of this executed in just 0.371 seconds (that’s part of the Quarkus “Supersonic Subatomic Java” experience).

Build the helloworld packaged JAR


Now that the code works as expected, it can be packaged using the command:

$ ./mvnw clean package

This command creates two JARs in the /target folder. The first is helloworld-<version>.jar, which is the standard artifact built from the Maven command with the project’s classes and resources. The second is helloworld-<version>-runner.jar, which is an executable JAR.

Please pay attention to the fact that this is not an uber-jar, because all of the dependencies are copied into the /target/lib folder (and not bundled within the JAR). Hence, to run this JAR in another location or host, both the JAR file and the libraries in the /lib folder have to be copied, considering that the Class-Path entry of the MANIFEST.MF file in the JAR explicitly lists the JARs from the lib folder.

To create an uber-jar application, please refer to the Uber-Jar Creation Quarkus guide.

Run the helloworld packaged JAR


Now, the packaged JAR can be executed using the standard java command:

$ java -jar ./target/helloworld-<version>-runner.jar INFO [io.quarkus] (main) Quarkus 0.23.2 started in 0.673s. Listening on: http://0.0.0.0:8080 INFO [io.quarkus] (main) Profile prod activated. INFO [io.quarkus] (main) Installed features: [cdi] 

As done above, open the http://0.0.0.0:8080 URL in a browser, and test that everything works.

Build the helloworld quickstart-native executable


So far so good. The helloworld quickstart ran as a standalone Java application using Quarkus dependencies, but more can be achieved by adding a further step to the modernization path: Build a native executable.

Install GraalVM


First of all, the tools for creating the native executable have to be installed:

  1. Download GraalVM 19.2.0.1 from https://github.com/oracle/graal/releases/tag/vm-19.2.0.1.
  2. Untar the file using the command:

$ tar xvzf graalvm-ce-linux-amd64-19.2.0.1.tar.gz

  1. Go to the untar folder.
  2. Execute the following to download and add the native image component:

$ ./bin/gu install native-image

  1. Set the GRAALVM_HOME environment variable to the folder created in step two, for example:

$ export GRAALVM_HOME={untar-folder}/graalvm-ce-19.2.0.1)

More details and install instructions for other operating systems are available in Building a Native Executable—Prerequisites Quarkus guide.

Build the helloworld native executable


As stated in the Building a Native Executable—Producing a native executable Quarkus guide, “Let’s now produce a native executable for our application. It improves the startup time of the application and produces a minimal disk footprint. The executable would have everything to run the application including the ‘JVM’ (shrunk to be just enough to run the application), and the application.”

To create the native executable, the Maven native profile has to be enabled by executing:

$ ./mvnw package -Pnative

The build took me about 1:10 minutes and the result is the helloworld-<version>-runner file in the /target folder.

Run the helloworld native executable


The /target/helloworld-<version>-runner file created in the previous step. It’s executable, so running it is easy:

$ ./target/helloworld-<version>-runner INFO [io.quarkus] (main) Quarkus 0.23.2 started in 0.006s. Listening on: http://0.0.0.0:8080 INFO [io.quarkus] (main) Profile prod activated. INFO [io.quarkus] (main) Installed features: [cdi] 

As done before, open the http://0.0.0.0:8080 URL in a browser and test that everything is working.

Next steps


I believe that this modernization, even of a basic application, is the right way to approach a brownfield application using technologies available in Quarkus. This way, you can start facing the issues and tackling them to understand and learn how to solve them.

In part two of this series, I’ll look at how to capture memory consumption data in order to evaluate performance improvements, which is a fundamental part of the modernization process.

Share

The post Quarkus: Modernize “helloworld” JBoss EAP quickstart, Part 1 appeared first on Red Hat Developer.



https://www.sickgaming.net/blog/2019/11/...rt-part-1/

Print this item

  [Tut] 7 Ways to Make Money as a Coder – Without a Job
Posted by: xSicKxBot - 03-22-2022, 05:39 PM - Forum: Python - No Replies

7 Ways to Make Money as a Coder – Without a Job



https://www.sickgaming.net/blog/2021/01/...out-a-job/

Print this item

  [Oracle Blog] AMC 2.11 is Released!
Posted by: xSicKxBot - 03-22-2022, 05:39 PM - Forum: Java Language, JVM, and the JRE - No Replies

AMC 2.11 is Released!

The Advanced Management Console (AMC) 2.11 release is now available. AMC is a commercial product available as part of Oracle Java Standard Edition (SE) Advanced and Oracle Java SE Suite. AMC helps you manage the use of different Java versions and Java applications in your enterprise. This release of...

https://blogs.oracle.com/java/post/amc-211-is-released

Print this item

  [Tut] Stripe One Time Payment with Prebuilt Hosted Checkout in PHP
Posted by: xSicKxBot - 03-22-2022, 05:39 PM - Forum: PHP Development - No Replies

Stripe One Time Payment with Prebuilt Hosted Checkout in PHP

Last modified on October 6th, 2020.

Stripe provides payment processing to support eCommerce software and mobile APPs. The key features by Stripe are,

  • fast and interactive checkout experience.
  • secure, smooth payment flow.
  • scope to uplift the conversion rate and business growth.

Stripe is the most popular payment gateway solution supporting card payments along with PayPal. Its complete documentation helps developers to do an effortless integration.

Stripe provides different types of payment services to accept payments. It supports accepting one-time payment, recurring payment, in-person payment and more.

There are two ways to set up the Stripe one-time payment option in a eCommerce website.

  1. Use the secure prebuilt hosted checkout page.
  2. Create a custom payment flow.

Let us take the first method to integrate Stripe’s one-time payment. The example code redirects customers to the Stripe hosted checkout page. It’s a pre-built page that allows customers to enter payment details.

Stripe hosted checkout option piggybacks on the Stripe trust factor. If your website is lesser-known, if you are not popular, then it is best to choose this option. Because the end users may feel uncomfortable to enter their card details on your page.

This diagram depicts the Stripe payment flow, redirect and response handling.

Stripe Hosted Checkout Block Diagram

In this example, it uses the latest checkout version to set up a one-time payment. If you want to create Stripe subscription payment, then the linked article has an example for it.

What is inside?


  1. About Stripe Checkout
  2. Steps to set up Stripe one-time payment flow
  3. About this example
  4. Generate and configure Stripe API keys
  5. Create webhook and map events
  6. Required libraries to access Stripe API
  7. Create client-server-side code to initiate checkout
  8. Capture and process webhook response
  9. Evaluate integration with test data
  10. Stripe one-time payment example output

About Stripe Checkout


Latest Stripe Checkout provides a frictionless smooth checkout experience. The below list shows some features of the latest Stripe checkout version.

  • Strong Customer Authentication (SCA).
  • Checkout interface fluidity over various devices’ viewport.
  • Multilingual support.
  • Configurable options to enable billing address collection, email receipts, and Button customizations

If you are using the legacy version,  it’s so simple to migrate to the latest Stripe Checkout version. The upgraded version supports advanced features like 3D secure, mobile payments and more.

Steps to setup Stripe one-time payment flow


The below steps are the least needs to set up a Stripe one-time payment online.

  1. Register with Stripe and generate API keys.
  2. Configure API keys with the application.
  3. Install and load the required libraries to access API.
  4. Create client and server-side code to make payments.
  5. Create endpoints to receive payment response and log into a database.
  6. Create a UI template to acknowledge customers.

We will see the above steps in this article with example code and screenshots.

About Stripe payment integration example


Stripe API allows applications to access and use its online payment services. It provides Stripe.js a JavaScript library to initiate the payment session flow.

This example code imports the Stripe libraries to access the API functions. It sets the endpoint to build the request and receive the response.

The client and server-side code redirect customers to the Stripe hosted checkout page. In the callback handlers, it processes the payment response sent by the API.

This example uses a database to store payment entries. It uses MySQLi with prepared statements to execute queries.

This image shows the simple file architecture of this example.

Stripe Hosted Checkout File Structure

Get and configure Stripe API keys


Register and log in with Stripe to get the API keys. Stripe dashboard will show two keys publishable_key and secret_key.

These keys are the reference to validate the request during the authentication process.

Note: Once finish testing in a sandbox mode, Stripe requires to activate the account to get the live API keys.

Get Stripe API Keys

This code shows the constants created to configure the API keys for this example.

<?php
namespace Phppot; class Config
{ const ROOT_PATH = "https://your-domain/stripe-hosted"; /* Stripe API test keys */ const STRIPE_PUBLISHIABLE_KEY = ""; const STRIPE_SECRET_KEY = ""; /* PRODUCT CONFIGURATIONS BEGINS */ const PRODUCT_NAME = 'A6900 MirrorLess Camera'; const PRODUCT_IMAGE = Config::ROOT_PATH . '/images/camera.jpg'; const PRODUCT_PRICE = '289.61'; const CURRENCY = 'USD'; const PRODUCT_TYPE = 'good';
}

Create webhook and map events


Creating a webhook is a conventional way to get the payment notifications sent by the API. All payment gateway providers give the option to create webhook for callback.

In PayPal payment gateway integration article, we have seen the types of notification mechanisms supported by PayPal.

The code has the webhook endpoint registered with Stripe. It handles the API responses based on the event that occurred.

The below image shows the screenshot of the add-endpoint dialog. It populates the URL and the mapped events in the form fields.

Navigate via Developers->Webhooks and click the Add endpoint button to see the dialog.

Add Stripe Webhook Endpoint

Required libraries to access Stripe API


First, download and install the stripe-php library. This will help to send flawless payment initiation request to the Stripe API.

This command helps to install this library via Composer. It is also available to download from GitHub.

composer require stripe/stripe-php

Load Stripe.js JavaScript library into the page which has the checkout button. Load this file by using https://js.stripe.com/v3/ instead of having it in local.

<script src="https://js.stripe.com/v3/"></script>

Create client-server code to process checkout


This section includes the steps needed to create the client-server code for setting up the Stripe one-time payment.

  1. Add checkout button and load Stripe.js
  2. Create a JavaScript event handler to initiate checkout session
  3. Create PHP endpoint to post create-checkout-session request
  4. Redirect customers to the Stripe hosted checkout page
  5. Get checkout session-id from the response.

HTML page with Stripe checkout button


This page has HTML code to add the Stripe checkout button. It loads the Stripe.js library.

This page loads a JavaScript that initiates the checkout session and redirects the user to the prebuilt Stripe hosted checkout.

The Stripe hosted checkout form handles the card validation effectively. We have created a custom car validator for Authorize.net payment integration code. Hosted checkout is more secure than handling card details by custom handlers.

index.php

<?php
namespace Phppot;
?>
<html>
<title>Stripe Prebuilt Hosted Checkout</title>
<head>
<link href="css/style.css" type="text/css" rel="stylesheet" />
<script src="https://js.stripe.com/v3/"></script>
</head>
<body> <div class="phppot-container"> <h1>Stripe Prebuilt Hosted Checkout</h1> <div id="payment-box"> <img src="images/camera.jpg" /> <h4 class="txt-title">A6900 MirrorLess Camera</h4> <div class="txt-price">$289.61</div> <button id="checkout-button">Checkout</button> </div> </div> <script> var stripe = Stripe('<?php echo Config::STRIPE_PUBLISHIABLE_KEY; ?>'); var checkoutButton = document.getElementById('checkout-button'); checkoutButton.addEventListener('click', function() { fetch('create-checkout-session.php', { method: 'POST', }) .then(function(response) { return response.json(); }) .then(function(session) { return stripe.redirectToCheckout({ sessionId: session.id }); }) .then(function(result) { if (result.error) { alert(result.error.message); } }) .catch(function(error) { console.error('Error:', error); }); }); </script>
</body>
</html>

JavaScript event handler initiates checkout session


In the previous section, it loads a JavaScript to do the following.

  1. Instantiate Stripe Javascript library object with the reference of the Stripe Publishable key.
  2. Map the checkout button’s click event to initiate a create-checkout-session.
  3. Redirect customers to the Stripe hosted checkout page with the checkout session id.

It calls the PHP endpoint builds the API request params to start a checkout session.

Then it receives the checkout-session-id as returned by the PHP endpoint. The redirectToCheckout() method sends customers to the prebuilt checkout to complete the payment.

PHP endpoint processing create-checkout-session request


When clicking the checkout button, the JavaScript executes an AJAX request. It fetches the PHP endpoint processing the create-checkout-session request.

The below code shows how to create the Stripe checkout-session via API. The API request is with the required query parameters. It includes the product detail, unit amount, payment method and more.

Then the API will return the session object after processing this request. This endpoint parses the response and grab the session-id and return it.

ajax-endpoint/create-checkout-session.php

<?php
namespace Phppot; use Phppot\StripeService;
use Phppot\StripePayment; $orderReferenceId = rand(100000, 999999); require_once __DIR__ . "/../lib/StripeService.php";
require_once __DIR__ .'/../Common/Config.php'; require_once __DIR__ . '/../lib/StripePayment.php';
$stripePayment = new StripePayment(); $stripeService = new StripeService(); $currency = Config::CURRENCY; $orderId = $stripePayment->insertOrder(Config::PRODUCT_PRICE, $currency, $orderReferenceId, "Payment in-progress");
$unitAmount = Config::PRODUCT_PRICE * 100;
$session = $stripeService->createCheckoutSession($unitAmount, $orderId);
echo json_encode($session);

The StripeService is a PHP class created to build API requests and process responses.

The createCheckoutSession() function builds the param array for the create-checkout-session request.

This service also handles the webhook responses sent by the API. The API sends the response on the occurrences of the events mapped with the webhook endpoint URL.

lib/StripeService.php

<?php
namespace Phppot; require_once __DIR__ . '/../Common/Config.php'; class StripeService
{ function __construct() { require_once __DIR__ . "/../vendor/autoload.php"; // Set your secret key. Remember to set your live key in production! \Stripe\Stripe::setApiKey(Config::STRIPE_SECRET_KEY); } public function createCheckoutSession($unitAmount, $clientReferenceId) { $checkout_session = \Stripe\Checkout\Session::create([ 'payment_method_types' => ['card'], 'line_items' => [[ 'price_data' => [ 'currency' => Config::CURRENCY, 'unit_amount' => $unitAmount, 'product_data' => [ 'name' => Config::PRODUCT_NAME, 'images' => [Config::PRODUCT_IMAGE], ], ], 'quantity' => 1, ]], 'mode' => 'payment', 'client_reference_id' => $clientReferenceId, 'success_url' => Config::ROOT_PATH . '/success.php?session_id={CHECKOUT_SESSION_ID}', 'cancel_url' => Config::ROOT_PATH . '/index.php?status=cancel', ]); return $checkout_session; } public function captureResponse() { $payload = @file_get_contents('php://input'); $event = json_decode($payload); require_once __DIR__ . "/../lib/StripePayment.php"; $stripePayment = new StripePayment(); switch($event->type) { case "customer.created": $param["stripe_customer_id"] = $event->data->object->id; $param["email"] = $event->data->object->email; $param["customer_created_datetime"] = date("Y,m,d H:i:s", $event->data->object->created); $param["stripe_response"] = json_encode($event->data->object); $stripePayment->insertCustomer($param); break; case "checkout.session.completed": $param["order_id"] = $event->data->object->client_reference_id; $param["customer_id"] = $event->data->object->customer; $param["payment_intent_id"] = $event->data->object->payment_intent; $param["stripe_checkout_response"] = json_encode($event->data->object); $stripePayment->updateOrder($param); break; case "payment_intent.created": $param["payment_intent_id"] = $event->data->object->id; $param["payment_create_at"] = date("Y-m-d H:i:s", $event->data->object->created); $param["payment_status"] = $event->data->object->status; $param["stripe_payment_response"] = json_encode($event->data->object); $stripePayment->insertPayment($param); break; case "payment_intent.succeeded": $param["payment_intent_id"] = $event->data->object->id; $param["billing_name"] = $event->data->object->charges->data[0]->billing_details->name; $param["billing_email"] = $event->data->object->charges->data[0]->billing_details->email; $param["payment_last_updated"] = date("Y-m-d H:i:s", $event->data->object->charges->data[0]->created); $param["payment_status"] = $event->data->object->charges->data[0]->status; $param["stripe_payment_response"] = json_encode($event->data->object); $stripePayment->updatePayment($param); break; case "payment_intent.canceled": $param["payment_intent_id"] = $event->data->object->id; $param["billing_name"] = $event->data->object->charges->data[0]->billing_details->name; $param["billing_email"] = $event->data->object->charges->data[0]->billing_details->email; $param["payment_last_updated"] = date("Y-m-d H:i:s", $event->data->object->charges->data[0]->created); $param["payment_status"] = $event->data->object->charges->data[0]->status; $param["stripe_payment_response"] = json_encode($event->data->object); $stripePayment->updatePayment($param); break; case "payment_intent.payment_failed": $param["payment_intent_id"] = $event->data->object->id; $param["billing_name"] = $event->data->object->charges->data[0]->billing_details->name; $param["billing_email"] = $event->data->object->charges->data[0]->billing_details->email; $param["payment_last_updated"] = date("Y-m-d H:i:s", $event->data->object->charges->data[0]->created); $param["payment_status"] = $event->data->object->charges->data[0]->status; $param["stripe_payment_response"] = json_encode($event->data->object); $stripePayment->updatePayment($param); break; } http_response_code(200); }
}

Capture and process response


The capture-response.php file calls the StripeService class to handle the webhook response.

The registered webhook endpoint has the mapping for the events. The figure shows the mapped events and the webhook URL below.

Stripe Developers Webhook Detail

The captureResponse() function handles the API response based on the events that occurred.

On each event, it updates the customer, order database tables. It creates the payment response log to put entries into the tbl_stripe_response table.

webhook-ep/capture-response.php

<?php
namespace Phppot; use Phppot\StriService; require_once __DIR__ . "/../lib/StripeService.php"; $stripeService = new StripeService(); $stripeService->captureResponse(); ?>

It invokes the StripeService function captureResponse(). It calls StripePayment to store Orders, Customers and Payment data into the database.

The StripePayment class it uses DataSource to connect the database and access it.

lib/StripePayment.php

<?php
namespace Phppot; use Phppot\DataSource; class StripePayment
{ private $ds; function __construct() { require_once __DIR__ . "/../lib/DataSource.php"; $this->ds = new DataSource(); } public function insertOrder($unitAmount, $currency, $orderReferenceId, $orderStatus) { $orderAt = date("Y-m-d H:i:s"); $insertQuery = "INSERT INTO tbl_order(order_reference_id, amount, currency, order_at, order_status) VALUES (?, ?, ?, ?, ?) "; $paramValue = array( $orderReferenceId, $unitAmount, $currency, $orderAt, $orderStatus ); $paramType = "sisss"; $insertId = $this->ds->insert($insertQuery, $paramType, $paramValue); return $insertId; } public function updateOrder($param) { $paymentDetails = $this->getPaymentByIntent($param["payment_intent_id"]); if (! empty($paymentDetails)) { if($paymentDetails[0]["payment_status"] == "succeeded") { $paymentStatus = "Paid"; } else if($paymentDetails[0]["payment_status"] == "requires_source") { $paymentStatus = "Payment in-progress"; } $query = "UPDATE tbl_order SET stripe_customer_id = ?, stripe_payment_intent_id = ?, stripe_checkout_response = ?, order_status = ? WHERE id = ?"; $paramValue = array( $param["customer_id"], $param["payment_intent_id"], $param["stripe_checkout_response"], $paymentStatus, $param["order_id"] ); $paramType = "ssssi"; $this->ds->execute($query, $paramType, $paramValue); } } public function insertCustomer($customer) { $insertQuery = "INSERT INTO tbl_customer(stripe_customer_id, email, customer_created_datetime, stripe_response) VALUES (?, ?, ?, ?) "; $paramValue = array( $customer["stripe_customer_id"], $customer["email"], $customer["customer_created_datetime"], $customer["stripe_response"] ); $paramType = "ssss"; $this->ds->insert($insertQuery, $paramType, $paramValue); } public function insertPayment($param) { $insertQuery = "INSERT INTO tbl_payment(stripe_payment_intent_id, payment_create_at, payment_status, stripe_payment_response) VALUES (?, ?, ?, ?) "; $paramValue = array( $param["payment_intent_id"], $param["payment_create_at"], $param["payment_status"], $param["stripe_payment_response"] ); $paramType = "ssss"; $this->ds->insert($insertQuery, $paramType, $paramValue); } public function updatePayment($param) { $query = "UPDATE tbl_payment SET billing_name = ?, billing_email = ?, payment_last_updated = ?, payment_status = ?, stripe_payment_response = ? WHERE stripe_payment_intent_id = ?"; $paramValue = array( $param["billing_name"], $param["billing_email"], $param["payment_last_updated"], $param["payment_status"], $param["stripe_payment_response"], $param["payment_intent_id"] ); $paramType = "ssssss"; $this->ds->execute($query, $paramType, $paramValue); } public function getPaymentByIntent($paymentIntent) { $query = "SELECT * FROM tbl_payment WHERE stripe_payment_intent_id = ?"; $paramValue = array( $paymentIntent ); $paramType = "s"; $result = $this->ds->select($query, $paramType, $paramValue); return $result; }
}
?>

Showing success page after payment


As sent with the create-checkout-session request, Stripe invokes the success page URL after payment.

The below code has the payment success message to acknowledge customers.

success.php

<?php
namespace Phppot; require_once __DIR__ . '/Common/Config.php';
?>
<html>
<head>
<title>Payment Response</title>
<link href="./css/style.css" type="text/css" rel="stylesheet" />
</head>
<body> <div class="phppot-container"> <h1>Thank you for shopping with us.</h1> <p>You have purchased "<?php echo Config::PRODUCT_NAME; ?>" successfully.</p> <p>You have been notified about the payment status of your purchase shortly.</p> </div>
</body>
</html>

Database script


Import the following SQL script to execute this example in your environment. It has the SQL to create tables created for this example and to build a relationship between them.

sql/structure.sql

--
-- Table structure for table `tbl_customer`
-- CREATE TABLE `tbl_customer` ( `id` int(11) NOT NULL, `stripe_customer_id` varchar(255) NOT NULL, `email` varchar(50) NOT NULL, `customer_created_datetime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, `stripe_response` text NOT NULL, `create_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=latin1; -- -------------------------------------------------------- --
-- Table structure for table `tbl_order`
-- CREATE TABLE `tbl_order` ( `id` int(11) NOT NULL, `order_reference_id` varchar(255) NOT NULL, `stripe_customer_id` varchar(255) DEFAULT NULL, `stripe_payment_intent_id` varchar(255) DEFAULT NULL, `amount` decimal(10,2) NOT NULL, `currency` varchar(10) NOT NULL, `order_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, `order_status` varchar(25) NOT NULL, `stripe_checkout_response` text NOT NULL, `create_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=latin1; -- -------------------------------------------------------- --
-- Table structure for table `tbl_payment`
-- CREATE TABLE `tbl_payment` ( `id` int(11) NOT NULL, `stripe_payment_intent_id` varchar(255) NOT NULL, `payment_create_at` timestamp NULL DEFAULT NULL, `payment_last_updated` timestamp NULL DEFAULT '0000-00-00 00:00:00', `billing_name` varchar(255) NOT NULL, `billing_email` varchar(255) NOT NULL, `payment_status` varchar(255) NOT NULL, `stripe_payment_response` text NOT NULL, `create_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=latin1; --
-- Indexes for dumped tables
-- --
-- Indexes for table `tbl_customer`
--
ALTER TABLE `tbl_customer` ADD PRIMARY KEY (`id`), ADD UNIQUE KEY `stripe_customer_id` (`stripe_customer_id`); --
-- Indexes for table `tbl_order`
--
ALTER TABLE `tbl_order` ADD PRIMARY KEY (`id`), ADD KEY `stripe_payment_intent_id` (`stripe_payment_intent_id`), ADD KEY `stripe_customer_id` (`stripe_customer_id`); --
-- Indexes for table `tbl_payment`
--
ALTER TABLE `tbl_payment` ADD PRIMARY KEY (`id`), ADD UNIQUE KEY `stripe_payment_intent_id` (`stripe_payment_intent_id`); --
-- AUTO_INCREMENT for dumped tables
-- --
-- AUTO_INCREMENT for table `tbl_customer`
--
ALTER TABLE `tbl_customer` MODIFY `id` int(11) NOT NULL AUTO_INCREMENT; --
-- AUTO_INCREMENT for table `tbl_order`
--
ALTER TABLE `tbl_order` MODIFY `id` int(11) NOT NULL AUTO_INCREMENT; --
-- AUTO_INCREMENT for table `tbl_payment`
--
ALTER TABLE `tbl_payment` MODIFY `id` int(11) NOT NULL AUTO_INCREMENT; --
-- Constraints for dumped tables
-- --
-- Constraints for table `tbl_order`
--
ALTER TABLE `tbl_order` ADD CONSTRAINT `tbl_order_ibfk_1` FOREIGN KEY (`stripe_payment_intent_id`) REFERENCES `tbl_payment` (`stripe_payment_intent_id`), ADD CONSTRAINT `tbl_order_ibfk_2` FOREIGN KEY (`stripe_customer_id`) REFERENCES `tbl_customer` (`stripe_customer_id`);
COMMIT;

Evaluate integration with test data


After integrating Stripe one-time payment, evaluate the integration with test card details.

The following test card details help to try a successful payment flow.

Card Number 4242424242424242
Expiry Month/Year Any future date
CVV Three-digit number

Stripe provides more test card details to receive more types of responses.

Stripe one-time payment example output


This example displays a product tile with the Stripe Checkout button as shown below.

Stripe Payment Landing Page

On clicking the Checkout button, it redirects customers to the prebuilt Stripe hosted checkout page.

Stripe Hosted Checkout Page

After processing the payment, Stripe will redirect customers to the success page URL.

Payment Success Page

Conclusion


We have seen how to integrate the stripe hosted checkout in PHP with an example. Hope it is simple and easy to follow.

It helps to have a quick glance with the bullet points pre-requisites, implementation steps. It pinpoints the todo items in short.

The downloadable source code has the required vendor files. It is not needed to download libraries and SDK from anywhere.

With database intervention, the code is ready to integrate with a full-fledged application.

With the latest Stripe checkout version, it provides payment services with SCA and more advanced features.

Download

↑ Back to Top



https://www.sickgaming.net/blog/2020/10/...ut-in-php/

Print this item

  (Indie Deal) ?Fantastic Tales Bundle, Transport Giveaways, Ziggurat & Maximum Sales
Posted by: xSicKxBot - 03-22-2022, 05:39 PM - Forum: Deals or Specials - No Replies

?Fantastic Tales Bundle, Transport Giveaways, Ziggurat & Maximum Sales

Transportation Giveaways
[www.indiegala.com]

https://youtu.be/OwuTYwuKUEw
Fantastic Tales Bundle | 8 eBooks | 94% OFF
[www.indiegala.com]
Get ready for a fantastic journey in the realm of fiction, fantasy and sci-fi with an eBook collection bringing Ancestors, Retropunk, Hope: All Alone, Alpha Gods: Omnibus & DGM Sleaze Castle: The Director's Cut.

Ziggurat & Maximum Games Sales, up to 92% OFF
[www.indiegala.com]
[www.indiegala.com]

https://www.youtube.com/watch?v=lxMD4lRupDk

Stay Inside, Stay Safe and Enjoy Good Games.
Check out IndieGala on Twitter, YouTube & Facebook[www.facebook.com]


https://steamcommunity.com/groups/indieg...3532924310

Print this item

  (Free Game Key) Dear Esther: Landmark Edition - Free Steam Game
Posted by: xSicKxBot - 03-22-2022, 05:39 PM - Forum: Deals or Specials - No Replies

Dear Esther: Landmark Edition - Free Steam Game

Visit the store page and add the game to your steam account:

Dear Esther: Landmark Edition

The game is free to keep for 3 days until 16th February

We are welcoming everyone to join our discord[discord.gg]. We are more active there on finding giveaways, small or large, and there are daily raffles you can participate.

?GrabFreeGames.com ?Twitter ?Steam Curator ?Facebook[fb.me]?Discord[discord.gg]
❤️Support us: ✔️HumbleBundle Partner[www.humblebundle.com] Epic Tag: GrabFreeGames


https://steamcommunity.com/groups/GrabFr...7788713192

Print this item

  PC - Atelier Sophie 2: The Alchemist of the Mysterious Dream
Posted by: xSicKxBot - 03-22-2022, 05:39 PM - Forum: New Game Releases - No Replies

Atelier Sophie 2: The Alchemist of the Mysterious Dream



A mysterious story of a mysterious dream...
One of the stories experienced throughout the Alchemist Sophie’s many adventures, as she continued her travels after leaving her hometown of Kirchen Bell.
This is Sophie’s adventure as she searches for her friend Plachta in the dream world Erde Wiege, where they become separated, and shows the bonds she forms with the people she meets and passing of hearts.

■Evolved turn-based battles & seamless transitions!
In the 6 member party turn-based battles, the 3 members in the front and 3 in the back form 2 teams cooperating “multi-linked turn battles”, and transitions from exploration to battles without loading times in “seamless battles”, the entire game can be enjoyed at a great pace.

■2 types of panels for everyone to enjoy synthesis!
This game uses panel synthesis, the synthesis system of the Mysterious series, where materials are placed in the panel slots to create new items in this puzzle-like feature. By placing the certain materials in the slots, various effects can be produced.
There are 2 types of panels in this game that players can select from : a regular panel and a restricted panel that has a higher synthesis difficulty level.
The board of the restricted panel is fairly complex, but when materials are placed just right, items with high effects can be synthesized, which can't be generated from the regular panel.

Publisher: Koei Tecmo Games

Release Date: Feb 25, 2022




https://www.metacritic.com/game/pc/ateli...ious-dream

Print this item

 
Latest Threads
Black Ops 2 (BO2,T6) 1.19...
Last Post: hotswagonme
31 minutes ago
Black Ops 2 GSC Studio | ...
Last Post: hotswagonme
1 hour ago
Black Ops 2 Jiggy v4.3 PC...
Last Post: MrEzlo
1 hour ago
Redacted T6 Nightly Offli...
Last Post: xavier_aeee
2 hours ago
Insta360 Coupon [INRSGY42...
Last Post: levlotus1998
4 hours ago
Insta360 Discount Code [I...
Last Post: levlotus1998
4 hours ago
Insta360 Coupon Codes | I...
Last Post: levlotus1998
4 hours ago
Insta360 Discount Code [I...
Last Post: levlotus1998
4 hours ago
Insta360 Discount Code | ...
Last Post: levlotus1998
4 hours ago
Insta360 Discount Code [I...
Last Post: levlotus1998
4 hours ago

Forum software by © MyBB Theme © iAndrew 2016